﻿using FluentAssertions.Execution;
using LunarSF.SHomeWorkshop.LunarMarkdownEditor.Utils.NPOIHelp;
using NPOI.SS.Formula.Functions;
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography.Pkcs;
using System.Security.RightsManagement;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using static IronPython.Modules.PythonRegex;
using static QRCoder.PayloadGenerator;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
    public class ReporterDefinition
    {
        public ReporterDefinition(string reportScript)
        {
            this.reportScript = reportScript;
        }

        private string _报表名称 = "";

        public string 报表名称 { get => _报表名称; set => _报表名称 = value; }

        /// <summary>
        /// 此方法改为手动调用——这样才能更好地获取出错的行号。从而提示用户进行处理。
        /// 警告：此方法会抛出异常，在引用时必须处理！！！
        /// </summary>
        public void BuildReportModel()
        {
            if (string.IsNullOrWhiteSpace(reportScript)) return;

            // 分解报表生成脚本，逐行解析命令
            var lines = reportScript.Split(new string[] { "\r\n", "\n", "\r" }, StringSplitOptions.None);

            ReporterWidget previewReporterWidget = null;
            ReporterPage previewReporterPage = null;
            int defaultRowNumber = 1;  // 本页默认行号
            int leftCellSpansCount = 0;  // 本行默认已使用的列数
            bool notFirstPage = false;   // 答题卡需要的两个部件“字符行、字符列”出现在第二个页面基本上是无意义的。

            for (int i = 0; i < lines.Length; i++)
            {
                // 逐行解析命令。
                var cmd = GetCommand(lines[i].TrimStart());
                if (cmd == null) continue;

                // 包括：
                //     创建块命令：新页眉、新页脚、新页面、新部件（新文本、新图像、新二维码）
                //     设置部件属性命令：前景、背景、行数、列数

                switch (cmd.CommandName)
                {
                    case "新页面":
                        {
                            if (previewReporterPage != null)
                            {
                                notFirstPage = true;
                            }

                            previewReporterWidget = null;
                            previewReporterPage = null;
                            defaultRowNumber = 1;  // 重置
                            leftCellSpansCount = 0;

                            var page = new ReporterPage(this)
                            {
                                PageSizeMark = this.DefaultPageSizeMark,
                                PageDirection = this.DefaultPageDirection,
                                LeftMargin = this.DefaultLeftMargin,
                                TopMargin = this.DefaultTopMargin,
                                RightMargin = this.DefaultRightMargin,
                                BottomMargin = this.DefaultBottomMargin,
                                PageRowsCount = this.DefaultPageRowsCount,
                                PageColumnsCount = this.DefaultPageColumnsCount,
                                // Foreground = this.DefaultForeground, // 页面不需要前景色
                                PageBackground = this.DefaultPageBackground,
                                LineColor = this.DefaultLineColor,
                                LineWidth = this.DefaultLineWidth,
                            };

                            var pageSize = page.PageSize;

                            int qWidth = (int)pageSize.Width / 4;
                            int qHeight = (int)pageSize.Height / 4;

                            if (page.LeftMargin > qWidth)
                                page.LeftMargin = qWidth;

                            if (page.TopMargin > qHeight)
                                page.TopMargin = qHeight;

                            if (page.RightMargin > qWidth)
                                page.RightMargin = qWidth;

                            if (page.BottomMargin > qHeight)
                                page.BottomMargin = qHeight;

                            Pages.Add(page);
                            previewReporterPage = page;  // 再设置

                            break;
                        }
                    case "新文本":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            var widget = new ReporterTextWdiget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                Background = this.DefaultBackground,
                                Foreground = this.DefaultForeground,
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新文本字段":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            var widget = new ReporterTextFieldWdiget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新字符行":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }

                            if (notFirstPage)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。字符行、字符列部件是为识别答题卡准备的，只允许出现在首页（其它页面对于读卡无意义）！", i + 1);
                            }

                            if (cmd.CommandValue != null && 
                                (cmd.CommandValue.Contains("|") || cmd.CommandValue.Contains("｜") ||
                                 cmd.CommandValue.Contains(":") || cmd.CommandValue.Contains("：")))
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。字符行列不能使用管道字符（“|”“｜”）或冒号（“:”“：”）或“+-*~”、圆花括号等特殊符号！", i + 1);
                            }

                            // 不应该自动创建页面
                            var widget = new ReporterCharsRowWdiget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新字符列":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }

                            if (notFirstPage)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。字符行、字符列部件是为识别答题卡准备的，只允许出现在首页（其它页面对于读卡无意义）！", i + 1);
                            }

                            if (cmd.CommandValue != null &&
                                (cmd.CommandValue.Contains("|") || cmd.CommandValue.Contains("｜") ||
                                 cmd.CommandValue.Contains(":") || cmd.CommandValue.Contains("：")))
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。字符行列不能使用管道字符（“|”“｜”）或冒号（“:”“：”）或“+-*~”、圆花括号等特殊符号！", i + 1);
                            }

                            // 不应该自动创建页面
                            var widget = new ReporterCharsColumnWdiget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新图像":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            var widget = new ReporterImageWidget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新图像字段":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            var widget = new ReporterImageFieldWidget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新二维码":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            var widget = new ReporterQrCoderWidget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新二维码字段":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            var widget = new ReporterQrCoderFieldWidget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新横线":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            var widget = new ReporterHLineWidget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新纵线":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            var widget = new ReporterVLineWidget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新外框":
                    case "新网格":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            var widget = new ReporterBoxWidget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新斜线":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            var widget = new ReporterSlashLineWidget(cmd.CommandValue, defaultRowNumber, leftCellSpansCount)
                            {
                                LocateAreaIndex = 0,
                            };
                            previewReporterPage.Widgets.Add(widget);
                            RefreshRowsAndColumnsCount(previewReporterPage, widget);
                            if (widget.CountWidthToAutoColumnIndexManager)
                            {
                                leftCellSpansCount += (widget.ColumnsCount < 0 ? 1 : widget.ColumnsCount);
                            }
                            previewReporterWidget = widget;

                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新页码":
                    case "新边栏文本":
                        {
                            // 不需要自动创建页面
                            var widget = new ReporterTextWdiget(cmd.CommandValue)
                            {
                                Background = this.DefaultBackground,
                                Foreground = this.DefaultForeground,
                            };
                            widget.SetAligmentByArea();
                            this.Widgets.Add(widget);
                            previewReporterWidget = widget;
                            previewReporterWidget.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新边栏文本字段":
                        {
                            // 不需要自动创建页面
                            var widget = new ReporterTextFieldWdiget(cmd.CommandValue);
                            widget.SetAligmentByArea();
                            this.Widgets.Add(widget);
                            previewReporterWidget = widget;
                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新边栏图像":
                        {
                            // 不需要自动创建页面
                            var widget = new ReporterImageWidget(cmd.CommandValue);
                            widget.SetAligmentByArea();
                            this.Widgets.Add(widget);
                            previewReporterWidget = widget;
                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新边栏图像字段":
                        {
                            // 不需要自动创建页面
                            var widget = new ReporterImageFieldWidget(cmd.CommandValue);
                            widget.SetAligmentByArea();
                            this.Widgets.Add(widget);
                            previewReporterWidget = widget;
                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新边栏二维码":
                        {
                            // 不需要自动创建页面
                            var widget = new ReporterQrCoderWidget(cmd.CommandValue);
                            widget.SetAligmentByArea();
                            this.Widgets.Add(widget);
                            previewReporterWidget = widget;
                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新边栏二维码字段":
                        {
                            // 不需要自动创建页面
                            var widget = new ReporterQrCoderFieldWidget(cmd.CommandValue);
                            widget.SetAligmentByArea();
                            this.Widgets.Add(widget);
                            previewReporterWidget = widget;
                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新边栏横线":
                        {
                            // 不需要自动创建页面
                            var widget = new ReporterHLineWidget(cmd.CommandValue);
                            // widget.SetAligmentByArea();  // 线型部件不应调用此方法，对齐无意义
                            this.Widgets.Add(widget);
                            previewReporterWidget = widget;
                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新边栏纵线":
                        {
                            // 不需要自动创建页面
                            var widget = new ReporterVLineWidget(cmd.CommandValue);
                            // widget.SetAligmentByArea();  // 线型部件不应调用此方法，对齐无意义
                            this.Widgets.Add(widget);
                            previewReporterWidget = widget;
                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新边栏外框":
                    case "新边栏网格":
                        {
                            // 不需要自动创建页面
                            var widget = new ReporterBoxWidget(cmd.CommandValue);
                            // widget.SetAligmentByArea();  // 线型部件不应调用此方法，对齐无意义
                            this.Widgets.Add(widget);
                            previewReporterWidget = widget;
                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "新边栏斜线":
                        {
                            // 不需要自动创建页面
                            var widget = new ReporterSlashLineWidget(cmd.CommandValue);
                            // widget.SetAligmentByArea();  // 线型部件不应调用此方法，对齐无意义
                            this.Widgets.Add(widget);
                            previewReporterWidget = widget;
                            previewReporterWidget?.SetValue(cmd.CommandValue);
                            break;
                        }
                    case "报表名称":
                        {
                            var shortName = cmd.CommandValue;
                            if(shortName.StartsWith("\\"))
                                shortName = shortName.TrimStart(new char[] { '\\' });

                            var destFilePath = Globals.PathOfWorkspaceAssetsFolder + shortName;
                            if(Utils.LFile.IsValidFilePath(destFilePath, false) == false)
                            {
                                throw new Exception($"第 {i + 1} 行出错。报表名称必须符合 Windows 系统文件名命名规则！");
                            }

                            this.报表名称 = shortName;
                            break;
                        }
                    case "默认图像目录路径":
                        {
                            this.DefaultImagesPath = cmd.CommandValue;
                            break;
                        }
                    case "默认字段图像目录路径":
                        {
                            this.DefaultFieldImagesPath = cmd.CommandValue;
                            break;
                        }
                    case "默认页面尺寸":
                        {
                            this.DefaultPageSizeMark = cmd.CommandValue;
                            break;
                        }
                    case "默认页面方向":
                        {
                            this.DefaultPageDirection = cmd.CommandValue;
                            break;
                        }
                    case "默认页面背景色":
                        {
                            this.DefaultPageBackground = cmd.CommandValue;
                            break;
                        }
                    case "默认页面左边距":
                        {
                            if (int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value < 19)
                                {
                                    this.DefaultLeftMargin = 19;
                                }
                                else
                                {
                                    this.DefaultLeftMargin = value;
                                }
                            }
                            else { this.DefaultLeftMargin = 76; }   // 约2cm
                            break;
                        }
                    case "默认页面上边距":
                        {
                            if (int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value < 19)
                                {
                                    this.DefaultTopMargin = 19;
                                }
                                else
                                {
                                    this.DefaultTopMargin = value;
                                }
                            }
                            else { this.DefaultTopMargin = 76; }   // 约2cm
                            break;
                        }
                    case "默认页面右边距":
                        {
                            if (int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value < 19)
                                {
                                    this.DefaultRightMargin = 19;
                                }
                                else
                                {
                                    this.DefaultRightMargin = value;
                                }
                            }
                            else { this.DefaultRightMargin = 76; }   // 约2cm
                            break;
                        }
                    case "默认页面下边距":
                        {
                            if (int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value < 19)
                                {
                                    this.DefaultRightMargin = 19;
                                }
                                else
                                {
                                    this.DefaultBottomMargin = value;
                                }
                            }
                            else { this.DefaultBottomMargin = 76; }   // 约2cm
                            break;
                        }
                    case "默认页面行数":
                        {
                            if (int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value < 1)
                                {
                                    this.DefaultPageRowsCount = 1;   // 行数至少为 1
                                }
                                else this.DefaultPageRowsCount = value;
                            }
                            else { this.DefaultPageRowsCount = 18; }  // 默认为 18
                            break;
                        }
                    case "默认页面列数":
                        {
                            if (int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value < 1)
                                {
                                    this.DefaultPageColumnsCount = 1;  // 列数至少为 1
                                }
                                else this.DefaultPageColumnsCount = value;
                            }
                            else { this.DefaultPageColumnsCount = 10; }  // 默认为 10
                            break;
                        }
                    case "默认边栏开关":  // 指定页面边栏区域的开关
                        {
                            var regexBarSwitcher = new Regex(@"[\(（][ 　\t]*(1[012]|[1-9]|[\*\+\-]|全部|所有|all|[左上右下](边栏)?)[ 　\t]*[\)）]");
                            var matchBarSwitcher = regexBarSwitcher.Match(cmd.CommandValue.ToLower());
                            if (matchBarSwitcher.Success)
                            {
                                var areaNumberTxt = matchBarSwitcher.Value.Trim(new char[] { ' ', '　', '\t', '(', '（', ')', '）' });
                                var tail = cmd.CommandValue.Substring(matchBarSwitcher.Length).Trim(new char[] { ' ', '　', '\t', '{', '}', '｛', '｝' });

                                switch (areaNumberTxt)
                                {
                                    case "1":
                                    case "2":
                                    case "3":
                                    case "4":
                                    case "5":
                                    case "6":
                                    case "7":
                                    case "8":
                                    case "9":
                                    case "10":
                                    case "11":
                                    case "12":  // 单独指定某一区域的开关
                                        {
                                            if (int.TryParse(areaNumberTxt, out int result))
                                            {
                                                switch (tail)
                                                {
                                                    case "t":
                                                    case "true":
                                                    case "真":
                                                    case "是":
                                                    case "开":
                                                    case "on":
                                                        {
                                                            this.DefaultBarSwitcher[result - 1] = true;
                                                            break;
                                                        }
                                                    case "f":
                                                    case "false":
                                                    case "假":
                                                    case "否":
                                                    case "关":
                                                    case "off":
                                                        {
                                                            this.DefaultBarSwitcher[result - 1] = false;
                                                            break;
                                                        }
                                                    default:
                                                        {
                                                            // 不识别的一律为真
                                                            this.DefaultBarSwitcher[result - 1] = true;
                                                            break;
                                                        }
                                                }
                                            }
                                            break;
                                        }
                                    case "*":
                                    case "全部":
                                    case "所有":
                                    case "all":
                                        //case "+":  // 保留，暂时只使用 *
                                        //case "-":
                                        {
                                            switch (tail)
                                            {
                                                case "t":
                                                case "true":
                                                case "真":
                                                case "是":
                                                case "开":
                                                case "on":
                                                    {
                                                        for (int areaIndex = 0; areaIndex < 12; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                                case "f":
                                                case "false":
                                                case "假":
                                                case "否":
                                                case "关":
                                                case "off":
                                                    {
                                                        for (int areaIndex = 0; areaIndex < 12; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = false;
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    {
                                                        // 不识别的一律为真
                                                        for (int areaIndex = 0; areaIndex < 12; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                            }
                                            break;
                                        }
                                    case "l":
                                    case "lft":
                                    case "left":
                                    case "左":
                                    case "左边栏":   // 标号 7、8、9，对应索引 6-8
                                        {
                                            switch (tail)
                                            {
                                                case "t":
                                                case "true":
                                                case "真":
                                                case "是":
                                                case "开":
                                                case "on":
                                                    {
                                                        for (int areaIndex = 6; areaIndex < 9; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                                case "f":
                                                case "false":
                                                case "假":
                                                case "否":
                                                case "关":
                                                case "off":
                                                    {
                                                        for (int areaIndex = 6; areaIndex < 9; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = false;
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    {
                                                        // 不识别的一律为真
                                                        for (int areaIndex = 6; areaIndex < 9; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                            }
                                            break;
                                        }
                                    case "t":
                                    case "tp":
                                    case "top":
                                    case "上":
                                    case "上边栏":   // 标号 1、2、3，对应索引 0-2
                                        {
                                            switch (tail)
                                            {
                                                case "t":
                                                case "true":
                                                case "真":
                                                case "是":
                                                case "开":
                                                case "on":
                                                    {
                                                        for (int areaIndex = 0; areaIndex < 3; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                                case "f":
                                                case "false":
                                                case "假":
                                                case "否":
                                                case "关":
                                                case "off":
                                                    {
                                                        for (int areaIndex = 0; areaIndex < 3; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = false;
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    {
                                                        // 不识别的一律为真
                                                        for (int areaIndex = 0; areaIndex < 3; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                            }
                                            break;
                                        }
                                    case "r":
                                    case "rt":
                                    case "rgt":
                                    case "right":
                                    case "右":
                                    case "右边栏":   // 标号 10、11、12，对应索引 9-11
                                        {
                                            switch (tail)
                                            {
                                                case "t":
                                                case "true":
                                                case "真":
                                                case "是":
                                                case "开":
                                                case "on":
                                                    {
                                                        for (int areaIndex = 9; areaIndex < 12; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                                case "f":
                                                case "false":
                                                case "假":
                                                case "否":
                                                case "关":
                                                case "off":
                                                    {
                                                        for (int areaIndex = 9; areaIndex < 12; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = false;
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    {
                                                        // 不识别的一律为真
                                                        for (int areaIndex = 9; areaIndex < 12; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                            }
                                            break;
                                        }
                                    case "b":
                                    case "bt":
                                    case "btm":
                                    case "bottom":
                                    case "下":
                                    case "下边栏":   // 标号 4、5、6，对应索引 3-5
                                        {
                                            switch (tail)
                                            {
                                                case "t":
                                                case "true":
                                                case "真":
                                                case "是":
                                                case "开":
                                                case "on":
                                                    {
                                                        for (int areaIndex = 3; areaIndex < 6; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                                case "f":
                                                case "false":
                                                case "假":
                                                case "否":
                                                case "关":
                                                case "off":
                                                    {
                                                        for (int areaIndex = 3; areaIndex < 6; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = false;
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    {
                                                        // 不识别的一律为真
                                                        for (int areaIndex = 3; areaIndex < 6; areaIndex++)
                                                        {
                                                            this.DefaultBarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                            }
                                            break;
                                        }
                                }
                            }
                            break;
                        }
                    case "显示辅助线":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "是":
                                case "显示":
                                case "y":
                                case "yes":
                                case "d":
                                case "display":
                                    {
                                        this.AssistLinesVisible = true; break;
                                    }
                                case "假":
                                case "否":
                                case "隐藏":
                                case "不显示":
                                case "n":
                                case "no":
                                case "h":
                                case "hide":
                                    {
                                        this.AssistLinesVisible = false; break;
                                    }
                                default:
                                    {
                                        this.AssistLinesVisible = null; break;
                                    }
                            }
                            break;
                        }
                    case "辅助线色":
                        {
                            this.AssistLinesColor = cmd.CommandValue;
                            break;
                        }
                    case "辅助线宽":
                        {
                            if (int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value >= 1)
                                {
                                    if (value > 10)
                                    {
                                        this.assistLinesWidth = 10;     // 辅助线宽度最大为 10
                                    }
                                    else
                                    {
                                        this.AssistLinesWidth = value;
                                    }
                                }
                                else this.assistLinesWidth = 1;  // 辅助线参与布局，宽度至少为 1
                            }
                            else this.assistLinesWidth = 1;
                            break;
                        }
                    case "辅助线型":
                        {
                            this.AssistLinesType = cmd.CommandValue;
                            break;
                        }
                    case "默认真值":
                        {
                            DefaultTrueValuesText = cmd.CommandValue;
                            break;
                        }
                    case "默认假值":
                        {
                            DefaultFalseValuesText = cmd.CommandValue;
                            break;
                        }
                    case "默认背景色":
                        {
                            this.DefaultBackground = cmd.CommandValue;
                            break;
                        }
                    case "默认外框部件背景色":
                        {
                            this.DefaultBoxBackground = cmd.CommandValue;
                            break;
                        }
                    case "默认前景色":
                        {
                            this.DefaultForeground = cmd.CommandValue;
                            break;
                        }
                    case "错误字段前景色":
                        {
                            this.ErrorMessageForeground = cmd.CommandValue;
                            break;
                        }
                    case "默认线色":
                        {
                            this.DefaultLineColor = cmd.CommandValue;
                            break;
                        }
                    case "默认线宽":
                        {
                            var cmdVal = cmd.CommandValue.ToLower().Trim();
                            if (cmdVal == "_" || cmdVal == "-" || cmdVal == "——" || cmdVal == "—")
                            {
                                this.DefaultLineWidth = -1;
                            }
                            else
                            {
                                if (int.TryParse(cmd.CommandValue, out int value))
                                {
                                    this.DefaultLineWidth = value;
                                }
                                else { this.DefaultLineWidth = 1; }
                            }
                            break;
                        }
                    case "默认边框色":
                        {
                            this.DefaultBorderColor = cmd.CommandValue;
                            break;
                        }
                    case "默认边框宽":
                        {
                            var cmdVal = cmd.CommandValue.ToLower().Trim();
                            if (cmdVal == "_" || cmdVal == "-" || cmdVal == "——" || cmdVal == "—")
                            {
                                this.DefaultBorderWidth = -1;
                            }
                            else
                            {
                                if (int.TryParse(cmd.CommandValue, out int value))
                                {
                                    this.DefaultBorderWidth = value;
                                }
                                else { this.DefaultBorderWidth = 0; }
                            }
                            break;
                        }
                    case "默认线型":
                        {
                            this.DefaultLineDashType = cmd.CommandValue;
                            break;
                        }
                    case "默认外框线色":
                        {
                            this.DefaultBoxLineColor = cmd.CommandValue;
                            break;
                        }
                    case "默认外框线宽":
                        {
                            if (int.TryParse(cmd.CommandValue, out int value))
                            {
                                this.DefaultBoxLineWidth = value;
                            }
                            else { this.DefaultBoxLineWidth = 2; }
                            break;
                        }
                    case "默认外框线型":
                        {
                            this.DefaultBoxLineDashType = cmd.CommandValue;
                            break;
                        }
                    case "默认字体":
                        {
                            this.DefaultFontName = cmd.CommandValue;
                            break;
                        }
                    case "默认字号":
                        {
                            this.DefaultFontSize = cmd.CommandValue;
                            break;
                        }
                    case "默认加粗":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "t":
                                case "true":
                                case "b":
                                case "bold":
                                    {
                                        this.DefaultIsBold = true; break;
                                    }
                                default:
                                    {
                                        this.DefaultIsBold = false; break;
                                    }

                            }
                            break;
                        }
                    case "默认倾斜":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "t":
                                case "true":
                                case "i":
                                case "italic":
                                    {
                                        this.DefaultIsItalic = true; break;
                                    }
                                default:
                                    {
                                        this.DefaultIsItalic = false; break;
                                    }

                            }
                            break;
                        }
                    case "默认下划线":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "t":
                                case "true":
                                case "u":
                                case "under":
                                case "underline":
                                case "under_line":
                                case "under line":
                                    {
                                        this.DefaultIsUnderline = true; break;
                                    }
                                default:
                                    {
                                        this.DefaultIsUnderline = false; break;
                                    }
                            }
                            break;
                        }
                    case "默认删除线":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "t":
                                case "true":
                                case "u":
                                case "under":
                                case "underline":
                                case "under_line":
                                case "under line":
                                    {
                                        this.DefaultIsStrikeThrough = true; break;
                                    }
                                default:
                                    {
                                        this.DefaultIsStrikeThrough = false; break;
                                    }
                            }
                            break;
                        }
                    case "默认自动换行":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "t":
                                case "true":
                                case "w":
                                case "aw":
                                case "autowrap":
                                case "auto_wrap":
                                    {
                                        this.DefaultAutoWrap = true; break;
                                    }
                                default:
                                    {
                                        this.DefaultAutoWrap = false; break;
                                    }
                            }
                            break;
                        }
                    case "默认水平对齐":
                    case "默认对齐方式":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "l":
                                case "lt":
                                case "lft":
                                case "left":
                                case "左":
                                case "居左":
                                case "左齐":
                                case "左对齐":
                                    {
                                        this.DefaultAlignment = TextAlignment.Left; break;
                                    }
                                case "r":
                                case "rt":
                                case "rgt":
                                case "右":
                                case "居右":
                                case "右齐":
                                case "右对齐":
                                    {
                                        this.DefaultAlignment = TextAlignment.Right; break;
                                    }
                                default:
                                    {
                                        this.DefaultAlignment = TextAlignment.Center; break;
                                    }
                            }
                            break;
                        }
                    case "默认垂直对齐":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "t":
                                case "tp":
                                case "top":
                                case "上":
                                case "居上":
                                case "上齐":
                                case "上对齐":
                                    {
                                        this.DefaultVerticalAlignment = VerticalAlignment.Top; break;
                                    }
                                case "b":
                                case "bt":
                                case "bot":
                                case "bottom":
                                case "下":
                                case "居下":
                                case "下齐":
                                case "下对齐":
                                    {
                                        this.DefaultVerticalAlignment = VerticalAlignment.Bottom; break;
                                    }
                                default:
                                    {
                                        this.DefaultVerticalAlignment = VerticalAlignment.Center; break;
                                    }
                            }
                            break;
                        }
                    case "默认边栏显示模式":
                        {
                            if (Enum.TryParse<WidgetDisplayMode>(cmd.CommandValue.Trim().ToLower(), true, out WidgetDisplayMode result))
                            {
                                this.defaultBarWidgetDisplayMode = result;
                            }
                            else
                            {
                                this.defaultBarWidgetDisplayMode = WidgetDisplayMode.全部页;
                            }
                            break;
                        }
                    case "默认左边栏位置":
                        {
                            var cmdTxt = cmd.CommandValue;
                            if (string.IsNullOrWhiteSpace(cmdTxt) == false)
                            {
                                var spans = ChinesePinYin.FatAlphaAndNumbersToThin(cmdTxt).Split(new char[] { ',', '，' }, StringSplitOptions.RemoveEmptyEntries);
                                if (spans.Length == 2)
                                {
                                    if (int.TryParse(spans[0].Trim(), out int result1))
                                    {
                                        this.DefaultLeftColumnMargin1 = result1;
                                    }

                                    if (int.TryParse(spans[1].Trim(), out int result2))
                                    {
                                        this.DefaultLeftColumnMargin2 = result2;
                                    }
                                }
                            }
                            break;
                        }
                    case "默认右边栏位置":
                        {
                            var cmdTxt = cmd.CommandValue;
                            if (string.IsNullOrWhiteSpace(cmdTxt) == false)
                            {
                                var spans = ChinesePinYin.FatAlphaAndNumbersToThin(cmdTxt).Split(new char[] { ',', '，' }, StringSplitOptions.RemoveEmptyEntries);
                                if (spans.Length == 2)
                                {
                                    if (int.TryParse(spans[0].Trim(), out int result1))
                                    {
                                        this.DefaultRightColumnMargin1 = result1;
                                    }

                                    if (int.TryParse(spans[1].Trim(), out int result2))
                                    {
                                        this.DefaultRightColumnMargin2 = result2;
                                    }
                                }
                            }
                            break;
                        }
                    case "默认上边栏位置":
                        {
                            var cmdTxt = cmd.CommandValue;
                            if (string.IsNullOrWhiteSpace(cmdTxt) == false)
                            {
                                var spans = ChinesePinYin.FatAlphaAndNumbersToThin(cmdTxt).Split(new char[] { ',', '，' }, StringSplitOptions.RemoveEmptyEntries);
                                if (spans.Length == 2)
                                {
                                    if (int.TryParse(spans[0].Trim(), out int result1))
                                    {
                                        this.DefaultPageHeaderMargin1 = result1;
                                    }

                                    if (int.TryParse(spans[1].Trim(), out int result2))
                                    {
                                        this.DefaultPageHeaderMargin2 = result2;
                                    }
                                }
                            }
                            break;
                        }
                    case "默认下边栏位置":
                        {
                            var cmdTxt = cmd.CommandValue;
                            if (string.IsNullOrWhiteSpace(cmdTxt) == false)
                            {
                                var spans = ChinesePinYin.FatAlphaAndNumbersToThin(cmdTxt).Split(new char[] { ',', '，' }, StringSplitOptions.RemoveEmptyEntries);
                                if (spans.Length == 2)
                                {
                                    if (int.TryParse(spans[0].Trim(), out int result1))
                                    {
                                        this.DefaultPageFooterMargin1 = result1;
                                    }

                                    if (int.TryParse(spans[1].Trim(), out int result2))
                                    {
                                        this.DefaultPageFooterMargin2 = result2;
                                    }
                                }
                            }
                            break;
                        }
                    case "字段默认字体":
                        {
                            this.FieldDefaultFontName = cmd.CommandValue;
                            break;
                        }
                    case "字段默认字号":
                        {
                            if (int.TryParse(cmd.CommandValue, out int value))
                            {
                                this.FieldDefaultFontSize = value;
                            }
                            break;
                        }
                    case "字段默认加粗":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "t":
                                case "true":
                                case "b":
                                case "bold":
                                    {
                                        this.FieldDefaultIsBold = true; break;
                                    }
                                default:
                                    {
                                        this.FieldDefaultIsBold = false; break;
                                    }

                            }
                            break;
                        }
                    case "字段默认倾斜":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "t":
                                case "true":
                                case "i":
                                case "italic":
                                    {
                                        this.FieldDefaultIsItalic = true; break;
                                    }
                                default:
                                    {
                                        this.FieldDefaultIsItalic = false; break;
                                    }

                            }
                            break;
                        }
                    case "字段默认下划线":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "t":
                                case "true":
                                case "u":
                                case "under":
                                case "underline":
                                case "under_line":
                                case "under line":
                                    {
                                        this.FieldDefaultIsItalic = true; break;
                                    }
                                default:
                                    {
                                        this.FieldDefaultIsItalic = false; break;
                                    }
                            }
                            break;
                        }
                    case "字段默认自动换行":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "t":
                                case "true":
                                case "w":
                                case "aw":
                                case "autowrap":
                                case "auto_wrap":
                                    {
                                        this.FieldDefaultAutoWrap = true; break;
                                    }
                                default:
                                    {
                                        this.FieldDefaultAutoWrap = false; break;
                                    }
                            }
                            break;
                        }
                    case "字段默认对齐方式":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "l":
                                case "lt":
                                case "lft":
                                case "left":
                                case "左":
                                case "居左":
                                case "左齐":
                                case "左对齐":
                                    {
                                        this.FieldDefaultAlignment = TextAlignment.Left; break;
                                    }
                                case "r":
                                case "rt":
                                case "rgt":
                                case "右":
                                case "居右":
                                case "右齐":
                                case "右对齐":
                                    {
                                        this.FieldDefaultAlignment = TextAlignment.Right; break;
                                    }
                                default:
                                    {
                                        this.FieldDefaultAlignment = TextAlignment.Center; break;
                                    }
                            }
                            break;
                        }
                    case "字段默认垂直对齐":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "t":
                                case "tp":
                                case "top":
                                case "上":
                                case "居上":
                                case "上齐":
                                case "上对齐":
                                    {
                                        this.DefaultVerticalAlignment = VerticalAlignment.Top; break;
                                    }
                                case "b":
                                case "bt":
                                case "bot":
                                case "bottom":
                                case "下":
                                case "居下":
                                case "下齐":
                                case "下对齐":
                                    {
                                        this.DefaultVerticalAlignment = VerticalAlignment.Bottom; break;
                                    }
                                default:
                                    {
                                        this.DefaultVerticalAlignment = VerticalAlignment.Center; break;
                                    }
                            }
                            break;
                        }
                    case "填涂模式":
                        {
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "t":
                                case "true":
                                case "真":
                                case "是":
                                case "开":
                                case "on":
                                    {
                                        this.FillCharsRowOrColumn = true;
                                        break;
                                    }
                                default:
                                    {
                                        // 不识别的一律为真
                                        this.FillCharsRowOrColumn = false;
                                        break;
                                    }
                            }
                            break;
                        }
                    case "页面尺寸":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            // 不应该自动创建页面
                            if (previewReporterPage != null)
                                previewReporterPage.PageSizeMark = cmd.CommandValue;
                            break;
                        }
                    case "页面方向":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null)
                                previewReporterPage.PageDirection = cmd.CommandValue;
                            break;
                        }
                    case "页面背景色":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null)
                                previewReporterPage.PageBackground = cmd.CommandValue;
                            break;
                        }
                    case "页面左边距":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null && int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value < 19)
                                {
                                    previewReporterPage.LeftMargin = 19;
                                }
                                else
                                {
                                    previewReporterPage.LeftMargin = value;
                                }
                            }
                            else
                            {
                                previewReporterPage.LeftMargin = 76;
                            }
                            break;
                        }
                    case "页面上边距":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null && int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value < 19)
                                {
                                    previewReporterPage.TopMargin = 19;
                                }
                                else
                                {
                                    previewReporterPage.TopMargin = value;
                                }
                            }
                            else
                            {
                                previewReporterPage.TopMargin = 76;
                            }
                            break;
                        }
                    case "页面右边距":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null && int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value < 19)
                                {
                                    previewReporterPage.RightMargin = 19;
                                }
                                else
                                {
                                    previewReporterPage.RightMargin = value;
                                }
                            }
                            else
                            {
                                previewReporterPage.RightMargin = 76;
                            }
                            break;
                        }
                    case "页面下边距":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null && int.TryParse(cmd.CommandValue, out int value))
                            {
                                if (value < 19)
                                {
                                    previewReporterPage.BottomMargin = 19;
                                }
                                else
                                {
                                    previewReporterPage.BottomMargin = value;
                                }
                            }
                            else
                            {
                                previewReporterPage.BottomMargin = 76;
                            }
                            break;
                        }
                    case "页面行数":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null && int.TryParse(cmd.CommandValue, out int value))
                            {
                                previewReporterPage.PageRowsCount = value;
                            }
                            break;
                        }
                    case "页面列数":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null && int.TryParse(cmd.CommandValue, out int value))
                            {
                                previewReporterPage.PageColumnsCount = value;
                            }
                            break;
                        }
                    case "边栏开关":  // 指定页面边栏区域的开关
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            var regexBarSwitcher = new Regex(@"[\(（][ 　\t]*(1[012]|[1-9]|[\*\+\-]|全部|所有|all|[左上右下](边栏)?)[ 　\t]*[\)）]");
                            var matchBarSwitcher = regexBarSwitcher.Match(cmd.CommandValue.ToLower());
                            if (matchBarSwitcher.Success)
                            {
                                var areaNumberTxt = matchBarSwitcher.Value.Trim(new char[] { ' ', '　', '\t', '(', '（', ')', '）' });
                                var tail = cmd.CommandValue.Substring(matchBarSwitcher.Length).Trim(new char[] { ' ', '　', '\t', '{', '}', '｛', '｝' });

                                switch (areaNumberTxt)
                                {
                                    case "1":
                                    case "2":
                                    case "3":
                                    case "4":
                                    case "5":
                                    case "6":
                                    case "7":
                                    case "8":
                                    case "9":
                                    case "10":
                                    case "11":
                                    case "12":  // 单独指定某一区域的开关
                                        {
                                            if (int.TryParse(areaNumberTxt, out int result))
                                            {
                                                switch (tail)
                                                {
                                                    case "t":
                                                    case "true":
                                                    case "真":
                                                    case "是":
                                                    case "开":
                                                    case "on":
                                                        {
                                                            previewReporterPage.BarSwitcher[result - 1] = true;
                                                            break;
                                                        }
                                                    case "f":
                                                    case "false":
                                                    case "假":
                                                    case "否":
                                                    case "关":
                                                    case "off":
                                                        {
                                                            previewReporterPage.BarSwitcher[result - 1] = false;
                                                            break;
                                                        }
                                                    default:
                                                        {
                                                            // 不识别的一律为真
                                                            previewReporterPage.BarSwitcher[result - 1] = true;
                                                            break;
                                                        }
                                                }
                                            }
                                            break;
                                        }
                                    case "*":
                                    case "全部":
                                    case "所有":
                                    case "all":
                                        //case "+":  // 保留，暂时只使用 *
                                        //case "-":
                                        {
                                            switch (tail)
                                            {
                                                case "t":
                                                case "true":
                                                case "真":
                                                case "是":
                                                case "开":
                                                case "on":
                                                    {
                                                        for (int areaIndex = 0; areaIndex < 12; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                                case "f":
                                                case "false":
                                                case "假":
                                                case "否":
                                                case "关":
                                                case "off":
                                                    {
                                                        for (int areaIndex = 0; areaIndex < 12; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = false;
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    {
                                                        // 不识别的一律为真
                                                        for (int areaIndex = 0; areaIndex < 12; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                            }
                                            break;
                                        }
                                    case "左":
                                    case "左边栏":   // 标号 7、8、9，对应索引 6-8
                                        {
                                            switch (tail)
                                            {
                                                case "t":
                                                case "true":
                                                case "真":
                                                case "是":
                                                case "开":
                                                case "on":
                                                    {
                                                        for (int areaIndex = 6; areaIndex < 9; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                                case "f":
                                                case "false":
                                                case "假":
                                                case "否":
                                                case "关":
                                                case "off":
                                                    {
                                                        for (int areaIndex = 6; areaIndex < 9; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = false;
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    {
                                                        // 不识别的一律为真
                                                        for (int areaIndex = 6; areaIndex < 9; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                            }
                                            break;
                                        }
                                    case "上":
                                    case "上边栏":   // 标号 1、2、3，对应索引 0-2
                                        {
                                            switch (tail)
                                            {
                                                case "t":
                                                case "true":
                                                case "真":
                                                case "是":
                                                case "开":
                                                case "on":
                                                    {
                                                        for (int areaIndex = 0; areaIndex < 3; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                                case "f":
                                                case "false":
                                                case "假":
                                                case "否":
                                                case "关":
                                                case "off":
                                                    {
                                                        for (int areaIndex = 0; areaIndex < 3; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = false;
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    {
                                                        // 不识别的一律为真
                                                        for (int areaIndex = 0; areaIndex < 3; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                            }
                                            break;
                                        }
                                    case "右":
                                    case "右边栏":   // 标号 10、11、12，对应索引 9-11
                                        {
                                            switch (tail)
                                            {
                                                case "t":
                                                case "true":
                                                case "真":
                                                case "是":
                                                case "开":
                                                case "on":
                                                    {
                                                        for (int areaIndex = 9; areaIndex < 12; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                                case "f":
                                                case "false":
                                                case "假":
                                                case "否":
                                                case "关":
                                                case "off":
                                                    {
                                                        for (int areaIndex = 9; areaIndex < 12; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = false;
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    {
                                                        // 不识别的一律为真
                                                        for (int areaIndex = 9; areaIndex < 12; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                            }
                                            break;
                                        }
                                    case "下":
                                    case "下边栏":   // 标号 4、5、6，对应索引 3-5
                                        {
                                            switch (tail)
                                            {
                                                case "t":
                                                case "true":
                                                case "真":
                                                case "是":
                                                case "开":
                                                case "on":
                                                    {
                                                        for (int areaIndex = 3; areaIndex < 6; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                                case "f":
                                                case "false":
                                                case "假":
                                                case "否":
                                                case "关":
                                                case "off":
                                                    {
                                                        for (int areaIndex = 3; areaIndex < 6; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = false;
                                                        }
                                                        break;
                                                    }
                                                default:
                                                    {
                                                        // 不识别的一律为真
                                                        for (int areaIndex = 3; areaIndex < 6; areaIndex++)
                                                        {
                                                            previewReporterPage.BarSwitcher[areaIndex] = true;
                                                        }
                                                        break;
                                                    }
                                            }
                                            break;
                                        }
                                }
                            }
                            break;
                        }
                    case "行号前进":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (int.TryParse(cmd.CommandValue.Trim(), out int value))
                            {
                                if (value < 1)
                                {
                                    defaultRowNumber++;
                                }
                                else
                                {
                                    defaultRowNumber += value;
                                }
                            }
                            else
                            {
                                defaultRowNumber++;
                            }
                            leftCellSpansCount = 0; // 重置
                            break;
                        }
                    case "软续行":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.Text += cmd.CommandValue;
                            }
                            break;
                        }
                    case "硬续行":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.Text += "<br>" + cmd.CommandValue;
                            }
                            break;
                        }
                    case "前景色":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.Foreground = cmd.CommandValue;
                            }
                            break;
                        }
                    case "背景色":
                    case "外框部件背景色":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.Background = cmd.CommandValue;
                            }
                            break;
                        }
                    case "外框装饰器":
                        {
                            var switcher = false;
                            switch (cmd.CommandValue.ToLower())
                            {
                                case "真":
                                case "t":
                                case "true":
                                case "w":
                                case "aw":
                                case "autowrap":
                                case "auto_wrap":
                                    {
                                        switcher = true; break;
                                    }
                                default:
                                    {
                                        switcher = false; break;
                                    }
                            }

                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.Adorner = switcher;
                            }
                            break;
                        }
                    case "字体":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.FontName = cmd.CommandValue;
                            }
                            break;
                        }
                    case "字号":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {

                                previewReporterWidget.FontSize = cmd.CommandValue;
                            }
                            break;
                        }
                    case "加粗":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                switch (cmd.CommandValue.ToLower())
                                {
                                    case "真":
                                    case "t":
                                    case "true":
                                    case "b":
                                    case "bold":
                                        {
                                            previewReporterWidget.IsBold = true; break;
                                        }
                                    default:
                                        {
                                            previewReporterWidget.IsBold = false; break;
                                        }

                                }
                            }
                            break;
                        }
                    case "倾斜":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                switch (cmd.CommandValue.ToLower())
                                {
                                    case "真":
                                    case "t":
                                    case "true":
                                    case "i":
                                    case "italic":
                                        {
                                            previewReporterWidget.IsItalic = true; break;
                                        }
                                    default:
                                        {
                                            previewReporterWidget.IsItalic = false; break;
                                        }

                                }
                            }
                            break;
                        }
                    case "下划线":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                switch (cmd.CommandValue.ToLower())
                                {
                                    case "真":
                                    case "t":
                                    case "true":
                                    case "u":
                                    case "under":
                                    case "underline":
                                    case "under_line":
                                    case "under line":
                                        {
                                            previewReporterWidget.IsUnderline = true; break;
                                        }
                                    default:
                                        {
                                            previewReporterWidget.IsUnderline = false; break;
                                        }
                                }
                            }
                            break;
                        }
                    case "删除线":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                switch (cmd.CommandValue.ToLower())
                                {
                                    case "真":
                                    case "t":
                                    case "true":
                                    case "u":
                                    case "under":
                                    case "underline":
                                    case "under_line":
                                    case "under line":
                                        {
                                            previewReporterWidget.IsStrikeThrough = true; break;
                                        }
                                    default:
                                        {
                                            previewReporterWidget.IsStrikeThrough = false; break;
                                        }
                                }
                            }
                            break;
                        }
                    case "自动换行":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                switch (cmd.CommandValue.ToLower())
                                {
                                    case "真":
                                    case "t":
                                    case "true":
                                    case "w":
                                    case "aw":
                                    case "autowrap":
                                    case "auto_wrap":
                                        {
                                            previewReporterWidget.IsAutoWrap = true; break;
                                        }
                                    default:
                                        {
                                            previewReporterWidget.IsAutoWrap = false; break;
                                        }
                                }
                            }
                            break;
                        }
                    case "对齐方式":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                switch (cmd.CommandValue.ToLower())
                                {
                                    case "l":
                                    case "lt":
                                    case "lft":
                                    case "left":
                                    case "左":
                                    case "居左":
                                    case "左齐":
                                    case "左对齐":
                                        {
                                            previewReporterWidget.Alignment = TextAlignment.Left; break;
                                        }
                                    case "r":
                                    case "rt":
                                    case "rgt":
                                    case "右":
                                    case "居右":
                                    case "右齐":
                                    case "右对齐":
                                        {
                                            previewReporterWidget.Alignment = TextAlignment.Right; break;
                                        }
                                    default:
                                        {
                                            previewReporterWidget.Alignment = TextAlignment.Center; break;
                                        }
                                }
                            }
                            break;
                        }
                    case "垂直对齐":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                switch (cmd.CommandValue.ToLower())
                                {
                                    case "t":
                                    case "tp":
                                    case "top":
                                    case "上":
                                    case "居上":
                                    case "上齐":
                                    case "上对齐":
                                        {
                                            previewReporterWidget.VerticalAlignment = VerticalAlignment.Top; break;
                                        }
                                    case "r":
                                    case "rt":
                                    case "rgt":
                                    case "右":
                                    case "居右":
                                    case "右齐":
                                    case "右对齐":
                                        {
                                            previewReporterWidget.VerticalAlignment = VerticalAlignment.Bottom; break;
                                        }
                                    default:
                                        {
                                            previewReporterWidget.VerticalAlignment = VerticalAlignment.Center; break;
                                        }
                                }
                            }
                            break;
                        }
                    case "边栏显示模式":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                if (Enum.TryParse<WidgetDisplayMode>(cmd.CommandValue.Trim().ToLower(), true, out WidgetDisplayMode result))
                                {
                                    previewReporterWidget.BarDisplay = result;
                                }
                                else
                                {
                                    previewReporterWidget.BarDisplay = WidgetDisplayMode.全部页;
                                }
                            }
                            break;
                        }
                    case "左边栏位置":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null)
                            {
                                var cmdTxt = cmd.CommandValue;
                                if (string.IsNullOrWhiteSpace(cmdTxt) == false)
                                {
                                    var spans = ChinesePinYin.FatAlphaAndNumbersToThin(cmdTxt).Split(new char[] { ',', '，' }, StringSplitOptions.RemoveEmptyEntries);
                                    if (spans.Length == 2)
                                    {
                                        if (int.TryParse(spans[0].Trim(), out int result1))
                                        {
                                            previewReporterPage.LeftColumnMargin1 = result1;
                                        }

                                        if (int.TryParse(spans[1].Trim(), out int result2))
                                        {
                                            previewReporterPage.LeftColumnMargin2 = result2;
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    case "右边栏位置":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null)
                            {
                                var cmdTxt = cmd.CommandValue;
                                if (string.IsNullOrWhiteSpace(cmdTxt) == false)
                                {
                                    var spans = ChinesePinYin.FatAlphaAndNumbersToThin(cmdTxt).Split(new char[] { ',', '，' }, StringSplitOptions.RemoveEmptyEntries);
                                    if (spans.Length == 2)
                                    {
                                        if (int.TryParse(spans[0].Trim(), out int result1))
                                        {
                                            previewReporterPage.RightColumnMargin1 = result1;
                                        }

                                        if (int.TryParse(spans[1].Trim(), out int result2))
                                        {
                                            previewReporterPage.RightColumnMargin2 = result2;
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    case "上边栏位置":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null)
                            {
                                var cmdTxt = cmd.CommandValue;
                                if (string.IsNullOrWhiteSpace(cmdTxt) == false)
                                {
                                    var spans = ChinesePinYin.FatAlphaAndNumbersToThin(cmdTxt).Split(new char[] { ',', '，' }, StringSplitOptions.RemoveEmptyEntries);
                                    if (spans.Length == 2)
                                    {
                                        if (int.TryParse(spans[0].Trim(), out int result1))
                                        {
                                            previewReporterPage.PageHeaderMargin1 = result1;
                                        }

                                        if (int.TryParse(spans[1].Trim(), out int result2))
                                        {
                                            previewReporterPage.PageHeaderMargin2 = result2;
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    case "下边栏位置":
                        {
                            if (previewReporterPage == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建页面！", i + 1);
                            }
                            if (previewReporterPage != null)
                            {
                                var cmdTxt = cmd.CommandValue;
                                if (string.IsNullOrWhiteSpace(cmdTxt) == false)
                                {
                                    var spans = ChinesePinYin.FatAlphaAndNumbersToThin(cmdTxt).Split(new char[] { ',', '，' }, StringSplitOptions.RemoveEmptyEntries);
                                    if (spans.Length == 2)
                                    {
                                        if (int.TryParse(spans[0].Trim(), out int result1))
                                        {
                                            previewReporterPage.PageFooterMargin1 = result1;
                                        }

                                        if (int.TryParse(spans[1].Trim(), out int result2))
                                        {
                                            previewReporterPage.PageFooterMargin2 = result2;
                                        }
                                    }
                                }
                            }
                            break;
                        }
                    case "线色":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.LineColor = cmd.CommandValue;
                            }
                            break;
                        }
                    case "线宽":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                var cmdVal = cmd.CommandValue.ToLower().Trim();
                                if (cmdVal == "_" || cmdVal == "-" || cmdVal == "——" || cmdVal == "—")
                                {
                                    previewReporterWidget.LineWidth = -1;
                                }
                                else
                                {
                                    if (int.TryParse(cmd.CommandValue, out int value))
                                    {
                                        previewReporterWidget.LineWidth = value;
                                    }
                                }
                            }
                            break;
                        }
                    case "边框色":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.BorderColor = cmd.CommandValue;
                            }
                            break;
                        }
                    case "边框宽":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                var cmdVal = cmd.CommandValue.ToLower().Trim();
                                if (cmdVal == "_" || cmdVal == "-" || cmdVal == "——" || cmdVal == "—")
                                {
                                    previewReporterWidget.BorderWidth = -1;
                                }
                                else
                                {
                                    if (int.TryParse(cmd.CommandValue, out int value))
                                    {
                                        previewReporterWidget.BorderWidth = value;
                                    }
                                }
                            }
                            break;
                        }
                    case "线型":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.LineDashType = cmd.CommandValue;
                            }
                            break;
                        }
                    // case "框线型":   // Border 不支持线型
                    case "外框线色":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.BoxLineColor = cmd.CommandValue;
                            }
                            break;
                        }
                    case "外框线宽":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                if (int.TryParse(cmd.CommandValue, out int value))
                                {
                                    previewReporterWidget.BoxLineWidth = value;
                                }
                            }
                            break;
                        }
                    case "外框线型":
                        {
                            if (previewReporterWidget == null)
                            {
                                throw new ReportScriptCompileExpection($"第 {i + 1} 行出错。请先创建部件！", i + 1);
                            }
                            if (previewReporterWidget != null)
                            {
                                previewReporterWidget.LineDashType = cmd.CommandValue;
                            }
                            break;
                        }
                }
            }
        }

        private string reportScript = "";

        public string ReportScript { get => this.reportScript; }

        private void RefreshRowsAndColumnsCount(ReporterPage page, ReporterWidget widget)
        {
            if (page == null || widget == null) return;

            if (widget.ColumnsCount < 0)
            {
                widget.ColumnsCount = page.PageColumnsCount - widget.ColumnIndex + 1;
            }

            if (widget.RowsCount < 0)
            {
                widget.RowsCount = page.PageRowsCount - widget.RowIndex + 1;
            }
        }

        public static void PreviewReporter(string reportScript, 文字表 dataContext)
        {
            var preWindow = new MiniReportEditor(reportScript, true)
            {
                Owner = Globals.MainWindow,
                WindowStartupLocation = WindowStartupLocation.CenterScreen,
            };

            preWindow.LoadReportAndFillFirstRecord(dataContext);
            preWindow.Show();
        }

        public static ReporterCommand GetCommand(string cmdText)
        {
            if (string.IsNullOrWhiteSpace(cmdText)) return null;

            if (cmdText.StartsWith("^^"))
            {
                cmdText = "；硬续行：" + cmdText.Substring(2);
            }
            else if (cmdText.StartsWith("^"))
            {
                cmdText = "；软续行：" + cmdText.Substring(1);
            }

            var regex_pattern = @"^[；;][ 　\t]*[^:：]*?[ 　\t]*[：:]";
            var regex = new Regex(regex_pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline);
            var match = regex.Match(cmdText);
            if (match.Success == false || match.Length <= 0) return null;

            var cmdName = match.Value.Trim().ToLower();
            cmdName = Regex.Replace(cmdName, @"[ 　\t]{1,}", " ");

            if (string.IsNullOrEmpty(cmdName)) return null;

            return new ReporterCommand(cmdName.Trim(new char[] { ' ', '　', '\t', ';', '；', ':', '：' }),
                                       cmdText.Substring(match.Length).TrimStart(new char[] { ' ', '　', '\t', '：', ':' }).Trim());
        }

        // 每个页面的总行数由 HeaderSection FooterSection 和本页的 Rows 共同构成。

        public List<ReporterPage> Pages { get; } = new List<ReporterPage>();

        /// <summary>
        /// 出现在每一页四个边栏的重复性部件（如页眉、页脚、页码等）
        /// </summary>
        public List<ReporterWidget> Widgets { get; } = new List<ReporterWidget>();

        /// <summary>
        /// 页面尺寸。
        /// </summary>
        public string DefaultPageSizeMark { get; set; } = "A4";

        private string defaultImagePath = Globals.PathofWorkspaceImages;

        public string DefaultImagesPath
        {
            get
            {
                if (Directory.Exists(defaultImagePath))
                    return defaultImagePath;

                return Globals.PathofWorkspaceImages;
            }
            set
            {
                defaultImagePath = value;
            }
        }

        public bool? AssistLinesVisible { get; set; } = null;

        public string defaultFieldImagesPath = null;

        public string DefaultFieldImagesPath
        {
            get
            {
                if (Directory.Exists(defaultFieldImagesPath))
                    return defaultFieldImagesPath;

                return DefaultImagesPath;
            }
            set
            {
                defaultFieldImagesPath = value;
            }
        }


        /// <summary>
        /// 根据 PageSixeMark 和 PageDirection 从纸型信息中取出页面尺寸。
        /// </summary>
        public Size DefaultPageSize
        {
            get
            {
                PaperInfo pi = PaperInfo.GetPaperInfo(DefaultPageSizeMark);
                switch (DefaultPageDirection.ToLower())
                {
                    case "h":
                    case "horizontal":
                    case "横":
                    case "横向":
                        {
                            return new Size() { Width = pi.ShortSideWPFUnit, Height = pi.LongSideWPFUnit, };
                        }
                    default:
                        {
                            return new Size() { Height = pi.LongSideWPFUnit, Width = pi.ShortSideWPFUnit, };
                        }
                }
            }
        }

        public int DefaultLeftMargin { get; set; } = 76;   // 约2cm
        public int DefaultTopMargin { get; set; } = 76;   // 约2cm
        public int DefaultRightMargin { get; set; } = 76;   // 约2cm
        public int DefaultBottomMargin { get; set; } = 76;   // 约2cm


        /// <summary>
        /// 页面方向。（h|v）。
        /// </summary>
        public string DefaultPageDirection { get; set; } = "v";

        /// <summary>
        /// 边栏开关，共 12 个（后期不会扩展）；初始状态必定为 true。
        /// </summary>
        public bool[] DefaultBarSwitcher { get; set; } = new bool[12] {
            true, true, true, true,
            true, true, true, true,
            true, true, true, true,
        };

        /// <summary>
        /// 部件默认前景色。
        /// </summary>
        public string DefaultForeground { get; set; } = "Black";

        /// <summary>
        /// 错误字段前景色。
        /// </summary>
        public string ErrorMessageForeground { get; set; } = "Red";

        /// <summary>
        /// 部件默认背景色。
        /// </summary>
        public string DefaultBackground { get; set; } = "White";

        public string DefaultPageBackground { get; set; } = "White";

        /// <summary>
        /// HLineWidget or VLineWidget 默认线色彩。
        /// </summary>
        public string DefaultLineColor { get; set; } = "Black";

        private int? defaultLineWidth = null;
        /// <summary>
        /// HLineWidget or VLineWidget 默认线宽度。当此值为 null 时，会使用辅助线宽度。
        /// </summary>
        public int DefaultLineWidth  // 注意：这个属性对应的字段是 int? 型的，但这个属性本身则是 int 型的
        {
            get
            {
                if (defaultLineWidth != null && defaultLineWidth.HasValue)
                    return defaultLineWidth.Value;
                else return AssistLinesWidth;
            }
            set
            {
                this.defaultLineWidth = value;
            }
        }

        /// <summary>
        /// 内容部件默认边框色彩。
        /// </summary>
        public string DefaultBorderColor { get; set; } = "Black";

        private int? defaultBorderWidth = 0;
        /// <summary>
        /// 内容部件默认边框宽度。当此值为 null 时，会使用辅助线宽度。
        /// </summary>
        public int DefaultBorderWidth  // 注意：这个属性对应的字段是 int? 型的，但这个属性本身则是 int 型的
        {
            get
            {
                if (defaultBorderWidth != null && defaultBorderWidth.HasValue)
                    return defaultBorderWidth.Value;
                else return AssistLinesWidth;
            }
            set
            {
                this.defaultBorderWidth = value;
            }
        }

        public string DefaultBoxBackground = "透明色";

        /// <summary>
        /// HLineWidget or VLineWidget 默认线型。（划线|点划线|点点划线|实线）
        /// </summary>
        public string DefaultLineDashType { get; set; } = "实线";

        /// <summary>
        /// Box Widget 默认外框线色彩。
        /// </summary>
        public string DefaultBoxLineColor { get; set; } = "Black";

        /// <summary>
        /// Box Widget 默认框线宽度。
        /// </summary>
        public int DefaultBoxLineWidth { get; set; } = 2;

        /// <summary>
        /// Box Widget 默认线型。（划线|点划线|点点划线|实线）
        /// </summary>
        public string DefaultBoxLineDashType { get; set; } = "实线";

        /// <summary>
        /// 辅助线色彩。
        /// </summary>
        public string AssistLinesColor { get; set; } = "SkyBlue";

        private int assistLinesWidth = 1;
        /// <summary>
        /// 辅助线宽度，至少为 1，最大为 10。
        /// </summary>
        public int AssistLinesWidth
        {
            get
            {
                if (assistLinesWidth >= 1) return assistLinesWidth;
                else return 1;
            }
            set
            {
                assistLinesWidth = value;
            }
        }

        /// <summary>
        /// 辅助线型。（划线|点划线|点点划线|实线）
        /// </summary>
        public string AssistLinesType { get; set; } = "实线";

        public static string InnerTrueValuesText { get; set; } = "|真|真值|true|t|是|正|正确|r|right|合格|及格|达标|";

        public static string InnerFalseValuesText { get; set; } = "|假|假值|false|f|否|负|错误|w|wrong|不合格|不及格|达标|";

        public static string DefaultTrueValuesText { get; set; } = null;

        public static string DefaultFalseValuesText { get; set; } = null;

        /// <summary>
        /// 这个行数是包括 HeaderSection 中的行、FooterSection 中的行和本页的所有行的总数。
        /// </summary>
        public int DefaultPageRowsCount { get; set; } = 18;

        /// <summary>
        /// 这个列数是包括 HeaderSection 中的行、FooterSection 中的行和本页的所有行中最大的列数。
        /// </summary>
        public int DefaultPageColumnsCount { get; set; } = 10;

        #region 左边栏区域
        public int DefaultLeftColumnMargin1 { get; set; } = 19;

        public int DefaultLeftColumnMargin2 { get; set; } = 57;
        #endregion

        #region 右边栏区域
        public int DefaultRightColumnMargin1 { get; set; } = 19;

        public int DefaultRightColumnMargin2 { get; set; } = 57;
        #endregion

        #region 页眉区域
        public int DefaultPageHeaderMargin1 { get; set; } = 19;

        public int DefaultPageHeaderMargin2 { get; set; } = 57;
        #endregion

        #region 页眉区域
        public int DefaultPageFooterMargin1 { get; set; } = 19;

        public int DefaultPageFooterMargin2 { get; set; } = 57;
        #endregion

        #region 普通部件需要的默认属性

        public string DefaultFontName { get; set; } = "SimSun";

        public string DefaultFontSize { get; set; } = "12pt";

        public bool DefaultIsBold { get; set; } = true;   // 非字段部件默认加粗

        public bool DefaultIsItalic { get; set; } = false;

        public bool DefaultAutoWrap { get; set; } = true;

        public TextAlignment DefaultAlignment { get; set; } = TextAlignment.Center;

        public VerticalAlignment DefaultVerticalAlignment { get; set; } = VerticalAlignment.Center;

        public bool DefaultIsUnderline { get; set; } = false;

        public bool DefaultIsStrikeThrough { get; set; } = false;

        #endregion

        #region 字段部件需要的默认属性

        public string FieldDefaultFontName { get; set; } = "SimSun";

        public int FieldDefaultFontSize { get; set; } = 14;

        public bool FieldDefaultIsBold { get; set; } = false;  // 字段部件默认不加粗

        public bool FieldDefaultIsItalic { get; set; } = false;

        public bool FieldDefaultAutoWrap { get; set; } = true;

        /// <summary>
        /// 输出空答题卡时应关闭此选项；输出带答案的答题卡时应开启此选项。
        /// </summary>
        public bool CharsRowOrColFillMode { get; set; } = false;  // 当前报表中字符行、字符列部件是否启用填充模式。

        public TextAlignment FieldDefaultAlignment { get; set; } = TextAlignment.Center;

        public VerticalAlignment FieldDefaultVerticalAlignment { get; set; } = VerticalAlignment.Center;

        public bool FieldDefaultIsUnderline { get; set; } = false;

        public bool FieldDefaultIsStrikeThrough { get; set; } = false;

        #endregion

        public int PagesCount
        {
            get
            {
                return this.Pages.Count;
            }
        }

        /// <summary>
        /// 添加在边栏的页面部件——通常用作页眉、页脚、页码等重复性元素。
        /// </summary>
        public List<ReporterWidget> BarWidgets { get; set; } = new List<ReporterWidget>();

        private WidgetDisplayMode defaultBarWidgetDisplayMode;

        public WidgetDisplayMode DefaultBarWidgetDisplayMode { get => this.defaultBarWidgetDisplayMode; }

        /// <summary>
        /// 当前报表中的“字符行”“字符列”（选择题答案或准考证号填涂数字块）是否开启填涂模式。
        /// 此属性默认为 true。
        /// </summary>
        public bool FillCharsRowOrColumn { get; set; } = true;
    }

    public enum WidgetDisplayMode
    {
        全部页,
        奇数页,
        偶数页,
    }

    public class ReporterCommandNameManager
    {
        static ReporterCommandNameManager()
        {
            // 新建页面
            Names.Add(new ReporterCommandNameManager("新页面", new string[] { "new page", "new_page" }, CommandType.NewPageOrAddRowNumberCommand, "创建报表页面命令", "0"));

            // 新建版芯常规部件
            Names.Add(new ReporterCommandNameManager("新文本", new string[] { "new text", "new_text", "new widget", "new_txt" }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "1"));
            Names.Add(new ReporterCommandNameManager("新文本字段", new string[] { "new field", "new_field" }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "2"));
            Names.Add(new ReporterCommandNameManager("新图像", new string[] { "new picure", "new_picure", "new pic", "new_pic", "new image", "new_image", "new img", "new_img" }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "3"));
            Names.Add(new ReporterCommandNameManager("新图像字段", new string[] { "new picure field", "new_picure_field", "new pic field", "new_pic_field", "new image field", "new_image_field", "new img field", "new_img_field" }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "4"));
            Names.Add(new ReporterCommandNameManager("新二维码", new string[] { "new qrcode", "new_qrcode", "new qr", "new_qr" }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "5"));
            Names.Add(new ReporterCommandNameManager("新二维码字段", new string[] { "new qrcode field", "new_qrcode_field", "new qr field", "new_qr_field" }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "6"));
            Names.Add(new ReporterCommandNameManager("新横线", new string[] { "new horizontal line", "new_horizontal_line", "新横向线", "新水平线" }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "7"));
            Names.Add(new ReporterCommandNameManager("新纵线", new string[] { "new horizontal line", "new_horizontal_line", "新纵向线", "新垂直线", "新竖线" }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "8"));
            Names.Add(new ReporterCommandNameManager("新斜线", new string[] { "new slash", "new_slash", }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "9"));
            Names.Add(new ReporterCommandNameManager("新网格", new string[] { "new grid", "new_grid", "新网格线" }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "10"));
            Names.Add(new ReporterCommandNameManager("新外框", new string[] { "new box", "new_box", "new border", "new_border", "新框" }, CommandType.NewWidgetCommand, "在页面中创建部件命令", "11"));

            // 在页面中心创建答题卡专用数字或字母填涂行（或列）
            Names.Add(new ReporterCommandNameManager("新字符行", new string[] { "new chars row", "new_chars_row", "new chars line", "new_chars_line" }, CommandType.NewWidgetCommand, "在页面中创建部件命令\r\n★注意：此部件只应在出现在首页面！"));
            Names.Add(new ReporterCommandNameManager("新字符列", new string[] { "new chars column", "new_chars_column", "new chars col", "new_chars_col" }, CommandType.NewWidgetCommand, "在页面中创建部件命令\r\n★注意：此部件只应在出现在首页面！"));

            // 新建边栏相关部件
            Names.Add(new ReporterCommandNameManager("新边栏文本", new string[] { "new bar text", "new_bar_text", "new bar widget", "new_bar_txt" }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新页码", new string[] { "new page number", "new_page_number" }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新边栏文本字段", new string[] { "new bar field", "new_bar_field" }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新边栏图像", new string[] { "new bar picure", "new_bar_picure", "new bar pic", "new_bar_pic", "new bar image", "new_bar_image", "new bar img", "new_bar_img" }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新边栏图像字段", new string[] { "new bar picure field", "new_bar_picure_field", "new bar pic field", "new_bar_pic_field", "new bar image field", "new_bar_image_field", "new bar img field", "new_bar_img_field" }, CommandType.NewWidgetCommand, "在页面中创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新边栏二维码", new string[] { "new bar qrcode", "new_bar_qrcode", "new bar qr", "new_bar_qr" }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新边栏二维码字段", new string[] { "new bar qrcode field", "new_bar_qrcode_field", "new bar qr field", "new_bar_qr_field" }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新边栏横线", new string[] { "new bar horizontal line", "new_bar_horizontal_line", "新边栏横向线", "新边栏水平线" }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新边栏纵线", new string[] { "new bar horizontal line", "new_bar_horizontal_line", "新边栏纵向线", "新边栏垂直线", "新竖线" }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新边栏斜线", new string[] { "new bar slash", "new_bar_slash", }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新边栏网格", new string[] { "new bar grid", "new_bar_grid", "新边栏网格线" }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));
            Names.Add(new ReporterCommandNameManager("新边栏外框", new string[] { "new bar box", "new_bar_box", "new bar border", "new_bar_border", "新边栏框" }, CommandType.NewWidgetCommand, "在页面边栏指定区域创建部件命令"));

            Names.Add(new ReporterCommandNameManager("报表名称", new string[] { "report name", "report_name", "answer sheet name", "answer_sheet_name", "answer card name", "answer_card_name", "答题卡名称" }, CommandType.PropertySettingCommand, "设置报表属性命令，请注意要符合文件名命名规则", "0"));
            Names.Add(new ReporterCommandNameManager("默认图像目录路径", new string[] { "default image path", "default_image_path", "默认图像路径" }, CommandType.DefaultPropertySettingCommand, "设置报表默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认字段图像目录路径", new string[] { "default image field path", "default_image_field_path", "默认字段图像路径" }, CommandType.DefaultPropertySettingCommand, "设置报表默认属性命令"));

            Names.Add(new ReporterCommandNameManager("默认页面尺寸", new string[] { "default page size", "default_page_size", "default paper size", "default_paper_size", "默认纸型", "默认纸张类型", "default paper type", "default_paper_type" }, CommandType.DefaultPropertySettingCommand, "设置页面默认属性"));
            Names.Add(new ReporterCommandNameManager("默认页面方向", new string[] { "default page direct", "default_page_direct", "default paper direction", "default_paper_direction" }, CommandType.DefaultPropertySettingCommand, "设置页面默认属性"));
            Names.Add(new ReporterCommandNameManager("默认页面背景色", new string[] { "default page background", "default page backcolor", "default_page_background", "default_page_backcolor" }, CommandType.DefaultPropertySettingCommand, "设置页面默认属性"));

            Names.Add(new ReporterCommandNameManager("默认页面左边距", new string[] { "default left margin", "default_left_margin", "default margin left", "default_margin_left", "默认左边距" }, CommandType.DefaultPropertySettingCommand, "设置页面默认属性"));
            Names.Add(new ReporterCommandNameManager("默认页面上边距", new string[] { "default top margin", "default_top_margin", "default margin top", "default_margin_top", "默认上边距" }, CommandType.DefaultPropertySettingCommand, "设置页面默认属性"));
            Names.Add(new ReporterCommandNameManager("默认页面右边距", new string[] { "default right margin", "default_right_margin", "default margin right", "default_margin_right", "默认右边距" }, CommandType.DefaultPropertySettingCommand, "设置页面默认属性"));
            Names.Add(new ReporterCommandNameManager("默认页面下边距", new string[] { "default bottom margin", "default_bottom_margin", "default margin bottom", "default_margin_bottom", "默认下边距" }, CommandType.DefaultPropertySettingCommand, "设置页面默认属性"));
            Names.Add(new ReporterCommandNameManager("默认页面行数", new string[] { "default page rows count", "default_page_rows_count", "default page lines count", "default_page_lines_count" }, CommandType.DefaultPropertySettingCommand, "设置页面默认属性"));
            Names.Add(new ReporterCommandNameManager("默认页面列数", new string[] { "default page cols count", "default_page_cols_count", "default page columns count", "default_page_columns_count" }, CommandType.DefaultPropertySettingCommand, "设置页面默认属性"));
            Names.Add(new ReporterCommandNameManager("默认边栏开关", new string[] { "default page bar switcher", "default_page_bar_switcher" }, CommandType.PropertySettingCommand, "页面属性设置命令"));

            Names.Add(new ReporterCommandNameManager("错误字段前景色", new string[] { "error field foreground", "error_field_foreground" }, CommandType.DefaultPropertySettingCommand, "设置报表属性命令"));

            Names.Add(new ReporterCommandNameManager("显示辅助线", new string[] { "show assist lines", "show_assist_lines", "开启辅助线" }, CommandType.DefaultPropertySettingCommand, "设置报表属性命令"));
            Names.Add(new ReporterCommandNameManager("辅助线色", new string[] { "assist line color", "assist_line_color" }, CommandType.DefaultPropertySettingCommand, "设置报表属性命令"));
            Names.Add(new ReporterCommandNameManager("辅助线宽", new string[] { "assist line width", "assist_line_width", "行列间距", "line_space", "line space" }, CommandType.DefaultPropertySettingCommand, "设置报表属性命令"));
            Names.Add(new ReporterCommandNameManager("辅助线型", new string[] { "assist line type", "assist_line_type" }, CommandType.DefaultPropertySettingCommand, "设置报表属性命令"));

            Names.Add(new ReporterCommandNameManager("默认真值", new string[] { "true value text", "true_value_text", "真值字串" }, CommandType.DefaultPropertySettingCommand, "设置报表属性命令"));
            Names.Add(new ReporterCommandNameManager("默认假值", new string[] { "false value text", "false_value_text", "假值字串" }, CommandType.DefaultPropertySettingCommand, "设置报表属性命令"));

            // 这几个是部件需要的
            Names.Add(new ReporterCommandNameManager("默认背景色", new string[] { "default background", "default backcolor", "default_background", "default_backcolor" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认外框部件背景色", new string[] { "default box background", "default box backcolor", "default_box_background", "default_box_backcolor" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认前景色", new string[] { "default foreground", "default forecolor", "default_foreground", "default_forecolor" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));

            Names.Add(new ReporterCommandNameManager("默认线色", new string[] { "default line color", "default_line_color" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认线宽", new string[] { "default line width", "default_line_width" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认线型", new string[] { "default line type", "default_line_type" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));

            Names.Add(new ReporterCommandNameManager("默认边框色", new string[] { "default border color", "default_border_color", "默认框线色" }, CommandType.DefaultPropertySettingCommand, "设置报表中内容部件边框默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认边框宽", new string[] { "default border width", "default_border_width", "默认框线宽" }, CommandType.DefaultPropertySettingCommand, "设置报表中内容部件边框默认属性命令"));

            Names.Add(new ReporterCommandNameManager("默认外框线色", new string[] { "default out border color", "default_out_border_color", "default out box color", "default_out_box_color", "默认边框线色", "默认框线色" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认外框线宽", new string[] { "default out border width", "default_out_border_width", "default out box width", "default_out_box_width", "默认边框线宽", "默认框线宽" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认外框线型", new string[] { "default box line type", "default_box_line_type", "默认边框线型", "默认框线型" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));

            Names.Add(new ReporterCommandNameManager("默认字体", new string[] { "default font", "default font name", "default font family", "default_font_name", "default_font_family", "默认字体名", "默认字体名称" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认字号", new string[] { "default font size", "default_font_size" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认加粗", new string[] { "default font bold", "default_font_bold" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认倾斜", new string[] { "default font italic", "default_font_italic" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认下划线", new string[] { "default underline", "default under line", "default_under_line" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认自动换行", new string[] { "default wrap", "default auto wrap", "default_wrap", "default_auto_wrap", "默认换行" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认对齐方式", new string[] { "default align", "default_alignment", "默认水平对齐" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认垂直对齐", new string[] { "default vertical align", "default_vertical_alignment" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));

            Names.Add(new ReporterCommandNameManager("默认边栏显示模式", new string[] { "default display mode", "default_display_mode" }, CommandType.DefaultPropertySettingCommand, "设置报表中部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认左边栏位置", new string[] { "default left bar margins", "default_left_bar_margins" }, CommandType.DefaultPropertySettingCommand, "设置报表边栏默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认右边栏位置", new string[] { "default right bar margins", "default_right_bar_margins" }, CommandType.DefaultPropertySettingCommand, "设置报表边栏默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认上边栏位置", new string[] { "default top bar margins", "default_top_bar_margins", "默认页眉边栏坐标" }, CommandType.DefaultPropertySettingCommand, "设置报表边栏默认属性命令"));
            Names.Add(new ReporterCommandNameManager("默认下边栏位置", new string[] { "default bottom bar margins", "default_bottom_bar_margins", "默认页脚边栏坐标" }, CommandType.DefaultPropertySettingCommand, "设置报表边栏默认属性命令"));

            // 这几个是字段部件需要的
            Names.Add(new ReporterCommandNameManager("字段默认字体", new string[] { "field default font", "field default font name", "field default font family",
                                                                                    "field_default_font_name", "field_default_font_family", "字段默认字体名", "字段默认字体名称", }, CommandType.DefaultPropertySettingCommand, "设置报表中字段部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("字段默认字号", new string[] { "field default font size", "field_default_font_size" }, CommandType.DefaultPropertySettingCommand, "设置报表中字段部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("字段默认加粗", new string[] { "field default font bold", "field_default_font_bold" }, CommandType.DefaultPropertySettingCommand, "设置报表中字段部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("字段默认倾斜", new string[] { "field default font italic", "field_default_font_italic" }, CommandType.DefaultPropertySettingCommand, "设置报表中字段部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("字段默认下划线", new string[] { "field default underline", "field default under line", "field_default_under_line" }, CommandType.DefaultPropertySettingCommand, "设置报表中字段部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("字段默认删除线", new string[] { "field default strikethrougn", "field default strike througn", "field_default_strike_througn" }, CommandType.DefaultPropertySettingCommand, "设置报表中字段部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("字段默认自动换行", new string[] { "field default wrap", "field_default auto wrap", "field_default_wrap", "field_field_default_auto_wrap", "字段默认换行" }, CommandType.DefaultPropertySettingCommand, "设置报表中字段部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("字段默认对齐方式", new string[] { "field default align", "field_default_alignment", "字段默认水平对齐" }, CommandType.DefaultPropertySettingCommand, "设置报表中字段部件默认属性命令"));
            Names.Add(new ReporterCommandNameManager("字段默认垂直对齐", new string[] { "field default vertical align", "field_default_vertical_alignment" }, CommandType.DefaultPropertySettingCommand, "设置报表中字段部件默认属性命令"));

            // 设计答题卡时才使用，因用量极少，所以没有必要设置对应的默认属性！！！2025.8.18
            Names.Add(new ReporterCommandNameManager("外框装饰器", new string[] { "out box adorner", "out_border_adorner", "四角装饰器" }, CommandType.PropertySettingCommand, "设置部件属性命令"));
            // 字符行、字符列写成类似：
            //     ；新字符行：（2，3）[c]abcd
            // 时，[c] 是答案。此时应考虑输出空答题卡与带答案的答题卡。
            // 默认情况下，应输出带答案的效果，需要输出空答题卡时再手动关闭“填涂模式”。
            // 此命令是报表层级的。
            Names.Add(new ReporterCommandNameManager("填涂模式", new string[] { "fill mode", "fill_mode", "填涂字符", "填涂字符行", "填涂字符列", "填涂字符行列" }, CommandType.DefaultPropertySettingCommand, "设置部件属性命令"));

            // 为方便自动完成列表，移到头部
            // Names.Add(new ReporterCommandNameManager("新页面", new string[] { "new page", "new_page" }, CommandType.NewPageOrAddRowNumberCommand, "0"));

            Names.Add(new ReporterCommandNameManager("页面尺寸", new string[] { "page size", "page_size", "paper size", "paper_size", "纸型", "纸张类型", "paper type", "paper_type" }, CommandType.PropertySettingCommand, "页面属性设置命令"));
            Names.Add(new ReporterCommandNameManager("页面方向", new string[] { "page direct", "page_direct", "paper direction", "paper_direction" }, CommandType.PropertySettingCommand, "页面属性设置命令"));
            Names.Add(new ReporterCommandNameManager("页面背景色", new string[] { "page background", "page_background", "page backcolor", "page_backcolor", "paper background", "paper_background", "paper backcolor", "paper_backcolor" }, CommandType.PropertySettingCommand, "页面属性设置命令"));

            Names.Add(new ReporterCommandNameManager("页面左边距", new string[] { "left margin", "left_margin", "margin left", "margin_left", "左边距" }, CommandType.PropertySettingCommand, "页面属性设置命令"));
            Names.Add(new ReporterCommandNameManager("页面上边距", new string[] { "top margin", "top_margin", "margin top", "margin_top", "上边距" }, CommandType.PropertySettingCommand, "页面属性设置命令"));
            Names.Add(new ReporterCommandNameManager("页面右边距", new string[] { "right margin", "right_margin", "margin right", "margin_right", "右边距" }, CommandType.PropertySettingCommand, "页面属性设置命令"));
            Names.Add(new ReporterCommandNameManager("页面下边距", new string[] { "bottom margin", "bottom_margin", "margin bottom", "margin_bottom", "下边距" }, CommandType.PropertySettingCommand, "页面属性设置命令"));
            Names.Add(new ReporterCommandNameManager("页面行数", new string[] { "page rows count", "page_rows_count", "page lines count", "page_lines_count" }, CommandType.PropertySettingCommand, "页面属性设置命令"));
            Names.Add(new ReporterCommandNameManager("页面列数", new string[] { "page cols count", "page_cols_count", "page columns count", "page_columns_count" }, CommandType.PropertySettingCommand, "页面属性设置命令"));

            Names.Add(new ReporterCommandNameManager("边栏开关", new string[] { "page bar switcher", "page_bar_switcher" }, CommandType.PropertySettingCommand, "页面属性设置命令"));

            Names.Add(new ReporterCommandNameManager("行号前进", new string[] { "defult row index add", "default_row_index_add", "行号增加" }, CommandType.NewPageOrAddRowNumberCommand, "页面自动行号控制命令"));
            Names.Add(new ReporterCommandNameManager("软续行", new string[] { "soft join line", "soft_join_line", "软文本续行" }, CommandType.NewPageOrAddRowNumberCommand, "脚本字符串控制命令"));
            Names.Add(new ReporterCommandNameManager("硬续行", new string[] { "hard join line", "hard_join_line", "硬文本续行" }, CommandType.NewPageOrAddRowNumberCommand, "脚本字符串控制命令"));

            // 为方便自动完成列表，移动到头部
            //Names.Add(new ReporterCommandNameManager("新文本", new string[] { "new text", "new_text", "new widget", "new_txt" }, CommandType.NewWidgetCommand, "", "1"));
            //Names.Add(new ReporterCommandNameManager("新文本字段", new string[] { "new field", "new_field" }, CommandType.NewWidgetCommand, "", "2"));
            //Names.Add(new ReporterCommandNameManager("新图像", new string[] { "new picure", "new_picure", "new pic", "new_pic", "new image", "new_image", "new img", "new_img" }, CommandType.NewWidgetCommand, "", "3"));
            //Names.Add(new ReporterCommandNameManager("新图像字段", new string[] { "new picure field", "new_picure_field", "new pic field", "new_pic_field", "new image field", "new_image_field", "new img field", "new_img_field" }, CommandType.NewWidgetCommand, "", "4"));
            //Names.Add(new ReporterCommandNameManager("新二维码", new string[] { "new qrcode", "new_qrcode", "new qr", "new_qr" }, CommandType.NewWidgetCommand, "", "5"));
            //Names.Add(new ReporterCommandNameManager("新二维码字段", new string[] { "new qrcode field", "new_qrcode_field", "new qr field", "new_qr_field" }, CommandType.NewWidgetCommand, "", "6"));
            //Names.Add(new ReporterCommandNameManager("新横线", new string[] { "new horizontal line", "new_horizontal_line", "新横向线", "新水平线" }, CommandType.NewWidgetCommand, "", "7"));
            //Names.Add(new ReporterCommandNameManager("新纵线", new string[] { "new horizontal line", "new_horizontal_line", "新纵向线", "新垂直线", "新竖线" }, CommandType.NewWidgetCommand, "", "8"));
            //Names.Add(new ReporterCommandNameManager("新外框", new string[] { "new box", "new_box", "new border", "new_border", "新框线", "新框" }, CommandType.NewWidgetCommand, "", "9"));

            Names.Add(new ReporterCommandNameManager("前景色", new string[] { "foreground", "forecolor" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("背景色", new string[] { "background", "backcolor" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("外框部件背景色", new string[] { "box background", "box_backcolor" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("字体", new string[] { "font", "font name", "font family", "font_name", "font_family", "字体名", "字体名称" }, CommandType.PropertySettingCommand, "文本内容部件和外框部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("字号", new string[] { "font size", "font_size" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("加粗", new string[] { "font bold", "font_bold" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("倾斜", new string[] { "font italic", "font_italic" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("下划线", new string[] { "underline", "under line", "under_line" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("删除线", new string[] { "strikethrougn", "strike through", "strike through" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("自动换行", new string[] { "wrap", "auto wrap", "wrap", "auto_wrap", "换行" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("对齐方式", new string[] { "align", "alignment", "水平对齐" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("垂直对齐", new string[] { "vertical align", "vertical_alignment" }, CommandType.PropertySettingCommand, "文本内容部件属性设置命令"));

            Names.Add(new ReporterCommandNameManager("边栏显示模式", new string[] { "display mode", "display_mode" }, CommandType.PropertySettingCommand, "边栏部件属性设置命令（非边栏部件会忽略此属性）"));
            Names.Add(new ReporterCommandNameManager("左边栏坐标", new string[] { "left bar margins", "left_bar_margins" }, CommandType.PropertySettingCommand, "设置页面边栏默认属性命令"));
            Names.Add(new ReporterCommandNameManager("右边栏坐标", new string[] { "right bar margins", "right_bar_margins" }, CommandType.PropertySettingCommand, "设置页面边栏默认属性命令"));
            Names.Add(new ReporterCommandNameManager("上边栏坐标", new string[] { "top bar margins", "top_bar_margins", "默认页眉边栏坐标" }, CommandType.PropertySettingCommand, "设置页面边栏默认属性命令"));
            Names.Add(new ReporterCommandNameManager("下边栏坐标", new string[] { "bottom bar margins", "bottom_bar_margins", "默认页脚边栏坐标" }, CommandType.PropertySettingCommand, "设置页面边栏默认属性命令"));

            Names.Add(new ReporterCommandNameManager("线色", new string[] { "line color", "line_color", }, CommandType.PropertySettingCommand, "装饰线部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("线宽", new string[] { "line width", "line_width", }, CommandType.PropertySettingCommand, "装饰线部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("线型", new string[] { "line type", "line_type", }, CommandType.PropertySettingCommand, "装饰线部件属性设置命令"));

            Names.Add(new ReporterCommandNameManager("边框色", new string[] { "border color", "border_color", "框线色" }, CommandType.PropertySettingCommand, "内容部件边框属性设置命令"));
            Names.Add(new ReporterCommandNameManager("边框宽", new string[] { "border width", "border_width", "框线宽" }, CommandType.PropertySettingCommand, "内容部件边框属性设置命令"));

            Names.Add(new ReporterCommandNameManager("外框线色", new string[] { "box line color", "box_line_color", "框线色" }, CommandType.PropertySettingCommand, "外框部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("外框线宽", new string[] { "box line width", "box_line_width", "框线宽" }, CommandType.PropertySettingCommand, "外框部件属性设置命令"));
            Names.Add(new ReporterCommandNameManager("外框线型", new string[] { "box line type", "box_line_type", "框线型" }, CommandType.PropertySettingCommand, "外框部件属性设置命令"));
        }

        public static List<ReporterCommandNameManager> Names { get; } = new List<ReporterCommandNameManager>();

        /// <summary>
        /// 构造方法。
        /// </summary>
        /// <param name="name">命令名。</param>
        /// <param name="alias">命令别名数组。</param>
        public ReporterCommandNameManager(string name, string[] alias, CommandType type, string commandDescript, string preFix = "")
        {
            CommandName = name;
            CommandAlias = alias;
            CompletePrefix = preFix;
            CommandType = type;
            CommandDescript = commandDescript;
        }

        public CommandType CommandType { get; }

        /// <summary>
        /// 在自动提示窗口的前缀提示序号文本。
        /// </summary>
        public string CompletePrefix { get; set; } = "";

        public string CommandName { get; }

        public string CommandDescript { get; }

        public string[] CommandAlias { get; }

        public static string Format(string name)
        {
            if (string.IsNullOrWhiteSpace(name)) return null;

            foreach (var cc in ReporterCommandNameManager.Names)
            {
                if (cc.CommandName == name) return cc.CommandName;

                foreach (var ccalias in cc.CommandAlias)
                {
                    if (ccalias == name) return cc.CommandName;
                }
            }

            return null;
        }
    }

    /// <summary>
    /// 命令类别。
    /// </summary>
    public enum CommandType
    {
        /// <summary>
        /// 新建页面或行号加1命令。
        /// </summary>
        NewPageOrAddRowNumberCommand,

        /// <summary>
        /// 新建部件命令。
        /// </summary>
        NewWidgetCommand,

        /// <summary>
        /// 属性设置命令。
        /// </summary>
        PropertySettingCommand,

        /// <summary>
        /// 默认属性设置命令。
        /// </summary>
        DefaultPropertySettingCommand,
    }

    public class ReporterCommand
    {
        public ReporterCommand(string cmdName, string cmdValue)
        {
            commandName = ReporterCommandNameManager.Format(cmdName);
            commandValue = cmdValue;
        }

        private string commandName = "";
        public string CommandName { get { return commandName; } }

        private string commandValue = "";
        public string CommandValue
        {
            get
            {
                if (string.IsNullOrWhiteSpace(commandValue)) return "";

                return ChinesePinYin.FatAlphaAndNumbersToThin(commandValue.Trim(), true);
            }
        }
    }

    public class ReporterPage
    {
        public ReporterPage(ReporterDefinition rd)
        {
            this.MasterReporterDefinition = rd;
        }

        public ReporterDefinition MasterReporterDefinition { get; }

        public List<ReporterWidget> Widgets { get; } = new List<ReporterWidget>();

        /// <summary>
        /// 这个行数是包括 HeaderSection 中的行、FooterSection 中的行和本页的所有行的总数。
        /// </summary>
        public int PageRowsCount { get; set; }

        /// <summary>
        /// 这个列数是包括 HeaderSection 中的行、FooterSection 中的行和本页的所有行中最大的列数。
        /// </summary>
        public int PageColumnsCount { get; set; }

        /// <summary>
        /// 边栏开关，共 12 个（后期不会扩展）；初始状态必定为 null，此时取 ReporterDefinition 类实例的 DefaultBarSWitcher 属性的对应索引处的值。
        /// </summary>
        public bool?[] BarSwitcher { get; set; } = new bool?[12] {
            null, null, null, null,
            null, null, null, null,
            null, null, null, null,
        };

        /// <summary>
        /// 页面尺寸。
        /// </summary>
        public string PageSizeMark { get; set; } = "A4";

        /// <summary>
        /// 根据 PageSixeMark 和 PageDirection 从纸型信息中取出页面尺寸。
        /// </summary>
        public Size PageSize
        {
            get
            {
                PaperInfo pi = PaperInfo.GetPaperInfo(PageSizeMark);

                if (pi == null)
                {
                    pi = PaperInfo.GetPaperInfo("A4");
                }

                switch (PageDirection.ToLower())
                {
                    case "h":
                    case "horizontal":
                    case "横":
                    case "横向":
                        {
                            return new Size() { Width = pi.LongSideWPFUnit, Height = pi.ShortSideWPFUnit, };
                        }
                    default:
                        {
                            return new Size() { Height = pi.LongSideWPFUnit, Width = pi.ShortSideWPFUnit, };
                        }
                }
            }
        }

        public int LeftMargin { get; set; } = 76;   // 约2cm
        public int TopMargin { get; set; } = 76;   // 约2cm
        public int RightMargin { get; set; } = 76;   // 约2cm
        public int BottomMargin { get; set; } = 76;   // 约2cm

        /// <summary>
        /// 页面方向。（h|v）。
        /// </summary>
        public string PageDirection { get; set; } = "v";

        /// <summary>
        /// 页面不需要前景色。
        /// </summary>
        // public string Foreground { get; set; } = "Black";

        /// <summary>
        /// 页面背景色。
        /// </summary>
        public string PageBackground { get; set; } = "White";

        /// <summary>
        /// 网格内框线线默认色彩。
        /// </summary>
        public string LineColor { get; set; } = null;

        /// <summary>
        /// 网格内框线默认宽度。
        /// </summary>
        public int? LineWidth { get; set; } = null;

        private int leftOffset = 0;

        public int LeftOffset { get { return this.leftOffset; } }

        private int rightOffset = 0;

        public int RightOffset
        {
            get { return this.rightOffset; }
        }

        private int topOffset = 0;

        public int TopOffset
        {
            get { return this.topOffset; }
        }

        private int bottomOffset = 0;

        public int BottomOffset
        {
            get { return this.bottomOffset; }
        }

        private int actualContentWidth;
        /// <summary>
        /// 实际使用的 ContentWidth。
        /// 由于部件、辅助线只能是整数，所以 ContentWidth 除以列数后，总会有些剩余，这些剩余应均分给左、右边距。
        /// </summary>
        public int ActualContentWidth
        {
            get
            {
                return actualContentWidth;
            }
        }

        private int actualContentHeight;
        /// <summary>
        /// 实际使用的 ContentHeight。
        /// 由于部件、辅助线只能是整数，所以 ContentHeight 除以行数后，总会有些剩余，这些剩余应均分给上、下边距。
        /// </summary>
        public int ActualContentHeight
        {
            get
            {
                return actualContentHeight;
            }
        }

        private int contentWidth;
        /// <summary>
        /// 除左右留白之外中间用于承载内容的空间宽度。
        /// </summary>
        public int ContentWidth
        {
            get { return this.contentWidth; }
        }

        private int contentHeight;
        /// <summary>
        /// 除上下留白之外中间用于承载内容的空间高度。
        /// </summary>
        public int ContentHeight
        {
            get { return contentHeight; }
        }

        private int cellWidth;
        public int CellWidth
        {
            get
            {
                return cellWidth;
            }
        }

        private int cellHeight;
        public int CellHeight
        {
            get
            {
                return cellHeight;
            }
        }

        private Pt leftTopPoint;
        /// <summary>
        /// 实际布局时左上角的坐标点。指实际内容的左上角点，不含外框宽，不含辅助线宽。
        /// </summary>
        public Pt LeftTopPoint { get { return this.leftTopPoint; } }

        private Pt rightBottomPoint;
        /// <summary>
        /// 实际布局时右下角的坐标。指实际内容的右下角点外侧那个点（外框右下角正方形部分的左上角顶点）。
        /// </summary>
        public Pt RightBottomPoint { get { return this.rightBottomPoint; } }

        #region 上边栏可用区域（页眉）
        private Rect topArea;
        /// <summary>
        /// 包含所有三个子区域。
        /// </summary>
        public Rect TopArea { get => topArea; }

        private Rect area1;
        public Rect Area1 { get => area1; }

        private Rect area2;
        public Rect Area2 { get => area2; }

        private Rect area3;
        public Rect Area3 { get => area3; }
        #endregion

        #region 下边栏可用区域（页脚）
        private Rect bottomArea;
        /// <summary>
        /// 包含所有三个子区域。
        /// </summary>
        public Rect BottomArea { get => bottomArea; }

        private Rect area4;
        public Rect Area4 { get => area4; }

        private Rect area5;
        public Rect Area5 { get => area5; }

        private Rect area6;
        public Rect Area6 { get => area6; }
        #endregion

        #region 左边栏可用区域
        private Rect leftArea;
        /// <summary>
        /// 包含所有三个子区域。
        /// </summary>
        public Rect LeftArea { get => leftArea; }

        private Rect area7;
        public Rect Area7 { get => area7; }

        private Rect area8;
        public Rect Area8 { get => area8; }

        private Rect area9;
        public Rect Area9 { get => area9; }
        #endregion

        #region 右边栏可用区域
        private Rect rightArea;
        /// <summary>
        /// 包含所有三个子区域。
        /// </summary>
        public Rect RightArea { get => rightArea; }

        private Rect area10;
        public Rect Area10 { get => area10; }

        private Rect area11;
        public Rect Area11 { get => area11; }

        private Rect area12;
        public Rect Area12 { get => area12; }
        #endregion

        #region 左边栏区域定位边距
        public int? LeftColumnMargin1 { get; set; }

        public int? LeftColumnMargin2 { get; set; }
        #endregion

        #region 右边栏区域定位边距
        public int? RightColumnMargin1 { get; set; }

        public int? RightColumnMargin2 { get; set; }
        #endregion

        #region 页眉区域定位边距
        public int? PageHeaderMargin1 { get; set; }

        public int? PageHeaderMargin2 { get; set; }
        #endregion

        #region 页脚区域定位边距
        public int? PageFooterMargin1 { get; set; }

        public int? PageFooterMargin2 { get; set; }
        #endregion

        /// <summary>
        /// 在设置页面尺寸、上下左右边距、行数、列数后，必须手动调用此方法重新计算各行、行间分隔线及四边未使用的空间。
        /// </summary>
        public void RefreshLocation(int assistLineWidth)
        {
            var pageSize = this.PageSize;
            var qOfWidth = (int)(pageSize.Width / 4);
            var qOfHeight = (int)(pageSize.Height / 4);

            if (assistLineWidth < 1)
            {
                assistLineWidth = 1;
            }
            else if (assistLineWidth > 36)
            {
                assistLineWidth = 36;
            }

            var leftMargin = this.LeftMargin;
            if (leftMargin < 0)
                leftMargin = 0;
            else if (leftMargin > qOfWidth)
                leftMargin = qOfWidth;

            var rightMargin = this.RightMargin;
            if (rightMargin < 0)
                rightMargin = 0;
            else if (rightMargin > qOfWidth)
                rightMargin = qOfWidth;

            var topMargin = this.TopMargin;
            if (topMargin < 0)
                topMargin = 0;
            else if (topMargin > qOfHeight)
                topMargin = qOfHeight;

            var bottomMargin = this.BottomMargin;
            if (bottomMargin < 0)
                bottomMargin = 0;
            else if (bottomMargin > qOfHeight)
                bottomMargin = qOfHeight;

            #region 计算版芯坐标等
            this.contentWidth = (int)pageSize.Width - leftMargin - rightMargin - assistLineWidth * 2;   // 这里 assistLineWidth * 2 是外框
            this.contentHeight = (int)pageSize.Height - topMargin - bottomMargin - assistLineWidth * 2;

            var maxColumnsCount = (int)((this.contentWidth + assistLineWidth) / (10 + assistLineWidth));        // 11，是最小字号（8，对应6个pt）+上下各1像素+竖线
            var maxRowsCount = (int)((this.ContentHeight + assistLineWidth) / (10 + assistLineWidth));
            // 加上一个 assistLineWidth 是因为最后一列不需要竖线（外框会画），最后一行也不需要横线（同样由外框绘制）。

            var columnsCount = this.PageColumnsCount;
            if (columnsCount < 1)
                columnsCount = this.PageColumnsCount = 1;
            else if (columnsCount > maxColumnsCount)
                columnsCount = this.PageColumnsCount = maxColumnsCount;

            var rowsCount = this.PageRowsCount;
            if (rowsCount < 1)
                rowsCount = this.PageRowsCount = 1;
            else if (rowsCount > maxRowsCount)
                rowsCount = this.PageRowsCount = maxRowsCount;

            this.cellWidth = (int)(this.contentWidth / columnsCount) - assistLineWidth;
            this.actualContentWidth = (this.cellWidth + assistLineWidth) * columnsCount;  // 这样可以去除非整除带来的多余的点数

            this.cellHeight = (int)(this.contentHeight / rowsCount) - assistLineWidth;
            this.actualContentHeight = (this.cellHeight + assistLineWidth) * rowsCount;  // 同样去除非整除带来的多作的空间

            var hOffset = this.contentWidth - this.actualContentWidth;
            var halfOfHOffseet = (int)(hOffset / 2);
            if (hOffset % 2 == 0)
            {
                this.leftOffset = halfOfHOffseet;
                this.rightOffset = halfOfHOffseet;
            }
            else
            {
                this.leftOffset = halfOfHOffseet + 1;
                this.rightOffset = halfOfHOffseet;
            }

            var vOffset = this.contentHeight - this.actualContentHeight;
            var valfOfHOffseet = (int)(vOffset / 2);
            if (vOffset % 2 == 0)
            {
                this.topOffset = valfOfHOffseet;
                this.bottomOffset = valfOfHOffseet;
            }
            else
            {
                this.topOffset = valfOfHOffseet + 1;
                this.bottomOffset = valfOfHOffseet;
            }

            var outBorderWidth = assistLineWidth;

            this.leftTopPoint = new Pt(this.LeftMargin + this.LeftOffset + outBorderWidth, this.TopMargin + this.TopOffset + outBorderWidth);
            this.rightBottomPoint = new Pt(this.leftTopPoint.X + (this.cellWidth + assistLineWidth) * columnsCount - assistLineWidth,  // 尾列不带辅助线（由外框右边线代替了）
                this.leftTopPoint.Y + (this.cellHeight + assistLineWidth) * rowsCount - assistLineWidth);  // 尾行不带底边线（也由外框底线代替了） 
            #endregion

            #region 计算四边栏可用区域

            var leftM1P = (this.LeftColumnMargin1 != null && this.LeftColumnMargin1.HasValue) ? this.LeftColumnMargin1.Value : this.MasterReporterDefinition.DefaultLeftColumnMargin1;
            var leftM2P = (this.LeftColumnMargin2 != null && this.LeftColumnMargin2.HasValue) ? this.LeftColumnMargin2.Value : this.MasterReporterDefinition.DefaultLeftColumnMargin2;

            var halfLeftMargin = leftMargin / 2;
            var leftM1 = Math.Min(leftM1P, leftM2P); if (leftM1 < 0) leftM1 = 0; if (leftM1 > halfLeftMargin) leftM1 = halfLeftMargin;
            var leftM2 = Math.Max(leftM1P, leftM2P); if (leftM2 < halfLeftMargin + 1) leftM2 = halfLeftMargin + 1; if (leftM2 > leftMargin) leftM2 = leftMargin;

            var pageHeaderM1P = (this.PageHeaderMargin1 != null && this.PageHeaderMargin1.HasValue) ? this.PageHeaderMargin1.Value : this.MasterReporterDefinition.DefaultPageHeaderMargin1;
            var pageHeaderM2P = (this.PageHeaderMargin2 != null && this.PageHeaderMargin2.HasValue) ? this.PageHeaderMargin2.Value : this.MasterReporterDefinition.DefaultPageHeaderMargin2;

            var halfTopMargin = topMargin / 2;
            var pageHeaderM1 = Math.Min(pageHeaderM1P, pageHeaderM2P); if (pageHeaderM1 < 0) pageHeaderM1 = 0; if (pageHeaderM1 > halfTopMargin) pageHeaderM1 = halfTopMargin;
            var pageHeaderM2 = Math.Max(pageHeaderM1P, pageHeaderM2P); if (pageHeaderM2 < halfTopMargin + 1) pageHeaderM2 = halfTopMargin + 1; if (pageHeaderM2 > topMargin) pageHeaderM2 = topMargin;

            var rightM1P = (this.RightColumnMargin1 != null && this.RightColumnMargin1.HasValue) ? this.RightColumnMargin1.Value : this.MasterReporterDefinition.DefaultRightColumnMargin1;
            var rightM2P = (this.RightColumnMargin2 != null && this.RightColumnMargin2.HasValue) ? this.RightColumnMargin2.Value : this.MasterReporterDefinition.DefaultRightColumnMargin2;

            var halfRightMargin = rightMargin / 2;
            var rightM1 = Math.Max(rightM1P, rightM2P); if (rightM1 > rightMargin) rightM1 = rightMargin; if (rightM1 < halfRightMargin + 1) rightM1 = halfRightMargin + 1;
            var rightM2 = Math.Min(rightM1P, rightM2P); if (rightM2 < 0) rightM2 = 0; if (rightM2 > halfRightMargin) rightM2 = halfRightMargin;

            var pageFooterM1P = (this.PageFooterMargin1 != null && this.PageFooterMargin1.HasValue) ? this.PageFooterMargin1.Value : this.MasterReporterDefinition.DefaultPageFooterMargin1;
            var pageFooterM2P = (this.PageFooterMargin2 != null && this.PageFooterMargin2.HasValue) ? this.PageFooterMargin2.Value : this.MasterReporterDefinition.DefaultPageFooterMargin2;

            var halfBottomMargin = bottomMargin / 2;
            var pageFooterM1 = Math.Max(pageFooterM1P, pageFooterM2P); if (pageFooterM1 > bottomMargin) pageFooterM1 = bottomMargin; if (pageFooterM1 < halfBottomMargin + 1) pageFooterM1 = halfBottomMargin + 1;
            var pageFooterM2 = Math.Min(pageFooterM1P, pageFooterM2P); if (pageFooterM2 < 0) pageFooterM2 = 0; if (pageFooterM2 > halfBottomMargin) pageFooterM2 = halfBottomMargin;

            var pageHeaderOrFooterWidth = rightBottomPoint.X - leftTopPoint.X;
            var leftOrRightColumnHeight = rightBottomPoint.Y - leftTopPoint.Y;

            var w1Of3 = pageHeaderOrFooterWidth / 3;
            var h1Of3 = leftOrRightColumnHeight / 3;

            var pSize = this.PageSize;

            var leftOffset = MasterReporterDefinition.AssistLinesWidth;  //  + (this.ContentWidth - this.ActualContentWidth) / 2;
            var topOffset = MasterReporterDefinition.AssistLinesWidth * 2; // + (this.ContentHeight - this.ActualContentHeight);   // / 2;

            topArea = new Rect(leftOffset + LeftTopPoint.X, pageHeaderM1, pageHeaderOrFooterWidth, pageHeaderM2 - pageHeaderM1);
            area1 = new Rect(leftOffset + LeftTopPoint.X, pageHeaderM1, w1Of3, pageHeaderM2 - pageHeaderM1);
            area2 = new Rect(leftOffset + LeftTopPoint.X + w1Of3 + 1, pageHeaderM1, w1Of3, pageHeaderM2 - pageHeaderM1);
            area3 = new Rect(leftOffset + LeftTopPoint.X + w1Of3 * 2 + 2, pageHeaderM1, w1Of3, pageHeaderM2 - pageHeaderM1);

            bottomArea = new Rect(leftOffset + LeftTopPoint.X, pSize.Height - pageFooterM1, pageHeaderOrFooterWidth, pageFooterM1 - pageFooterM2);
            area4 = new Rect(leftOffset + LeftTopPoint.X, pSize.Height - pageFooterM1, w1Of3, pageFooterM1 - pageFooterM2);
            area5 = new Rect(leftOffset + LeftTopPoint.X + w1Of3 + 1, pSize.Height - pageFooterM1, w1Of3, pageFooterM1 - pageFooterM2);
            area6 = new Rect(leftOffset + LeftTopPoint.X + w1Of3 * 2 + 2, pSize.Height - pageFooterM1, w1Of3, pageFooterM1 - pageFooterM2);

            leftArea = new Rect(leftM1, topOffset + topMargin, leftM2 - leftM1, leftOrRightColumnHeight);
            area7 = new Rect(leftM1, topOffset + topMargin, leftM2 - leftM1, h1Of3);
            area8 = new Rect(leftM1, topOffset + topMargin + h1Of3 + 1, leftM2 - leftM1, h1Of3);
            area9 = new Rect(leftM1, topOffset + topMargin + h1Of3 * 2 + 2, leftM2 - leftM1, h1Of3);

            rightArea = new Rect(pSize.Width - rightM1, topOffset + topMargin, rightM1 - rightM2, leftOrRightColumnHeight);
            area10 = new Rect(pSize.Width - rightM1, topOffset + topMargin, rightM1 - rightM2, h1Of3);
            area11 = new Rect(pSize.Width - rightM1, topOffset + topMargin + h1Of3 + 1, rightM1 - rightM2, h1Of3);
            area12 = new Rect(pSize.Width - rightM1, topOffset + topMargin + h1Of3 * 2 + 2, rightM1 - rightM2, h1Of3);
            #endregion
        }

        internal Rect GetArea(int locateAreaIndex, bool isFullArea)
        {
            if (isFullArea)
            {
                switch (locateAreaIndex)
                {
                    case 1:
                    case 2:
                    case 3:
                        {
                            return topArea;
                        }
                    case 4:
                    case 5:
                    case 6:
                        {
                            return bottomArea;
                        }
                    case 7:
                    case 8:
                    case 9:
                        {
                            return leftArea;
                        }
                    case 10:
                    case 11:
                    case 12:
                        {
                            return RightArea;
                        }
                    default: return new Rect(LeftTopPoint.X, LeftTopPoint.Y, RightBottomPoint.X - LeftTopPoint.X, RightBottomPoint.Y - LeftTopPoint.Y);
                }
            }
            else
            {
                switch (locateAreaIndex)
                {
                    case 1: return area1;
                    case 2: return area2;
                    case 3: return area3;
                    case 4: return area4;
                    case 5: return area5;
                    case 6: return area6;
                    case 7: return area7;
                    case 8: return area8;
                    case 9: return area9;
                    case 10: return area10;
                    case 11: return area11;
                    case 12: return area12;
                    default: return new Rect(LeftTopPoint.X, LeftTopPoint.Y, RightBottomPoint.X - LeftTopPoint.X, RightBottomPoint.Y - LeftTopPoint.Y);
                }
            }
        }
    }

    public class Pt
    {
        public Pt(int x, int y)
        {
            this.x = x;
            this.y = y;
        }

        private int x;

        public int X { get { return x; } }

        private int y;

        public int Y { get { return y; } }
    }

    public enum ReporterWidgetType
    {
        ContentWidget,
        LineWidget,
    }

    public enum AreaLocation
    {
        /// <summary>
        /// 版芯位置，默认按行、列网格布局。
        /// </summary>
        CentralArea,
        /// <summary>
        /// 边栏区域，具体由位置编号决定。
        /// </summary>
        BarArea,
    }

    public abstract class ReporterWidget
    {
        /// <summary>
        /// 只适用于版芯出现的部件。
        /// </summary>
        /// <param name="text"></param>
        /// <param name="defaultRowNumber"></param>
        /// <param name="leftCellSpansCount"></param>
        public ReporterWidget(string text, int defaultRowNumber, int leftCellSpansCount)
        {
            this.Text = text;
            this.Area = AreaLocation.CentralArea;
            RefreshCentralLocation(defaultRowNumber, leftCellSpansCount);
        }

        /// <summary>
        /// 只适用于出现在四个边栏的部件。
        /// </summary>
        /// <param name="text"></param>
        public ReporterWidget(string text)
        {
            this.Text = text;
            this.Area = AreaLocation.BarArea;
            RefreshBarLocation();
        }

        public AreaLocation Area { get; set; } = AreaLocation.CentralArea;

        public ReporterWidgetType WidgetType { get; set; }

        protected string widgetTypeName = "ReporterWidget";

        public string WidgetTypeName
        {
            get { return widgetTypeName; }
        }

        public string Background { get; set; } = null;  // 这个不设置默认值，为 null 时访问“默认背景色”

        public string Foreground { get; set; } = null;  // 这个不设置默认值，为 null 时访问“默认前景色”

        #region 只有线型部件的线条使用这三个属性
        public string LineColor { get; set; } = null;

        /// <summary>
        /// 横线部件、纵线部件，宽度为 0 时不绘制；宽度 大于等于 1 时绘制（必须为整数）；小于 0 时绘制矩形覆盖当前行或当前列。
        /// 斜线部件，宽度为 0 时不绘制，宽度大于等于 1 时绘制；但小于 0 时也不绘制！！
        /// 
        /// 这三个装饰线与辅助线不同——辅助线宽度至少为 1。
        /// </summary>
        public int? LineWidth { get; set; } = null;

        public string LineDashType { get; set; } = null;
        #endregion

        #region 内容部件边框属性
        public string BorderColor { get; set; } = null;

        public int? BorderWidth { get; set; } = null;
        #endregion

        #region 只有 Box 会使用
        public string BoxLineColor { get; set; } = null;

        /// <summary>
        /// 作外框部件时（在上层）外框宽度为 0 时不绘制，外框小于 0 时，覆盖整个区域；外框大于等于 1 时，正常绘制外框。
        /// 作网格时，不使用此属性，也不使用 lineWidth 属性——而是使用辅助线宽来绘制网格线（宽度至少为 1）。
        /// </summary>
        public int? BoxLineWidth { get; set; } = null;

        public string BoxLineDashType { get; set; } = null;
        #endregion

        public int RowsCount { get; set; } = 1;   // 向下合并行，这个不需要设计“默认行数”属性

        public int ColumnsCount { get; set; } = 1;  // 向右合并列，这个不需要设置“默认列数”属性

        public string FontName { get; set; } = null;

        public string FontSize { get; set; } = null;

        public bool? IsBold { get; set; } = null;

        public bool? IsItalic { get; set; } = null;

        public bool? IsUnderline { get; set; } = null;

        public bool? IsStrikeThrough { get; set; } = null;

        public bool? IsAutoWrap { get; set; } = null;

        public TextAlignment? Alignment { get; set; } = null;

        /// <summary>
        /// 只有内容部件支持此属性。装饰线、框部件不应支持。
        /// </summary>
        public VerticalAlignment? VerticalAlignment { get; set; } = null;

        public virtual void SetValue(string value) { }

        /// <summary>
        /// 在网格中的横行坐标。
        /// </summary>
        public int RowIndex { get; set; }

        /// <summary>
        /// 在网格中的纵列坐标。
        /// </summary>
        public int ColumnIndex { get; set; }

        /// <summary>
        /// 左坐标。由 RowIndex、PageRowsCount、PageMargin 等计算而来。
        /// </summary>
        public int Left { get; set; }

        /// <summary>
        /// 顶坐标。由 ColumnIndex、PageColumnsCount、PageMargin 等计算而来。
        /// </summary>
        public int Right { get; set; }

        public string Text { get; set; } = "";   // 有时候需要空文本块

        /// <summary>
        /// 是否将此内容部件的宽度计入“自动列号管理器”，默认为 false。
        /// 注意：1. 线型装饰部件此属性总是 false。
        ///       2. 内容部件坐标中“列号”为“_”时，列号实际值由“自动列号管理器”动态设置。
        ///       3. 线型部件可以使用“_”作为列号，动态设置列号，但线型部件的列数（宽度）不计入“自列号管理器”。
        ///       2. 如果内容部件的“列数”为“_”时，此值也为 false，不计入“自动列号管理器”。
        /// </summary>
        public bool CountWidthToAutoColumnIndexManager { get; set; } = true;

        public static Regex RegLocation { get; } = new Regex(@"[ 　\t]*[\(（][ 　\t,，\d_\-—]*[\)）][ 　\t]*");

        public static string FormatLocationText(string locationText)
        {
            if (string.IsNullOrWhiteSpace(locationText)) return "";

            locationText = locationText.Trim(new char[] { ',', '，', ' ', '　', '\t', '(', '（', ')', '）' });
            locationText = Regex.Replace(locationText, @"[_\-—]{1,}", "_");

            var spans = locationText.Trim(new char[] { ' ', '　', '\t', '(', '（', ')', '）', })
                                    .Replace("-", "_").Replace("—", "_").Replace("__", "_")
                                    .Split(new char[] { ',', '，', }, StringSplitOptions.None);

            if (spans.Length <= 0) return "";

            var txt = new StringBuilder();
            txt.Append("（");
            for (int i = 0; i < Math.Min(spans.Length - 1, 4); i++)
            {
                if (string.IsNullOrWhiteSpace(spans[i]) == false)
                {
                    txt.Append(ChinesePinYin.FatAlphaAndNumbersToThin(spans[i].Trim()));
                }
                txt.Append("，");
            }
            txt.Append(spans[spans.Length - 1]);
            txt.Append("）");

            if (txt.ToString() == "（_）") return "（_，）";

            return txt.ToString();
        }

        private void RefreshCentralLocation(int defaultRowNumber = 1, int leftCellSpansCount = 0)
        {
            if (string.IsNullOrWhiteSpace(Text))
            {
                RowIndex = 1;
                ColumnIndex = 1;
                RowsCount = 1;
                ColumnsCount = 1;
                return;
            }

            var match = RegLocation.Match(Text);
            if (match.Success == false)
            {
                RowIndex = 1;
                ColumnIndex = 1;
                RowsCount = 1;
                ColumnsCount = 1;
                return;
            }

            this.Text = this.Text.Substring(match.Length).Trim();

            var locationTxt = match.Value.Trim(new char[] { ',', '，', ' ', '　', '\t', '(', '（', ')', '）' });
            locationTxt = Regex.Replace(locationTxt, @"[_\-—]{1,}", "_");
            var spans = locationTxt.Split(new char[] { ',', '，', }, StringSplitOptions.None);

            switch (spans.Length)
            {
                case 1:
                    {
                        // 只有列号
                        RowIndex = defaultRowNumber;
                        var span0Value = spans[0].Trim(new char[] { ' ', '　', '\t' });
                        if (span0Value == "_")
                        {
                            ColumnIndex = leftCellSpansCount;

                            // 只有内容部件才支持自动计算列宽和列号
                            CountWidthToAutoColumnIndexManager = (WidgetType == ReporterWidgetType.ContentWidget);
                        }
                        else
                        {
                            if (int.TryParse(span0Value, out int value))
                            {
                                ColumnIndex = value;
                            }
                            else ColumnIndex = 1;
                            CountWidthToAutoColumnIndexManager = false;
                        }
                        break;
                    }
                case 2:
                    {
                        // 行号、列号
                        // 行号
                        var span0Value = spans[0].Trim(new char[] { ' ', '　', '\t' });
                        if (span0Value == "_")
                        {
                            RowIndex = defaultRowNumber;
                        }
                        else
                        {
                            if (int.TryParse(span0Value, out int value))
                            {
                                RowIndex = value;
                            }
                            else { RowIndex = 1; }
                        }

                        // 列号
                        var span1Value = spans[1].Trim(new char[] { ' ', '　', '\t' });
                        if (span1Value == "_")
                        {
                            ColumnIndex = leftCellSpansCount + 1;
                            // 只有内容部件才支持自动计算列宽和列号
                            CountWidthToAutoColumnIndexManager = (WidgetType == ReporterWidgetType.ContentWidget);
                        }
                        else
                        {
                            if (int.TryParse(span1Value, out int value2))
                            {
                                ColumnIndex = value2;
                            }
                            else ColumnIndex = 1;
                            CountWidthToAutoColumnIndexManager = false;
                        }

                        break;
                    }
                case 3:
                    {
                        // 行号、列号、行数
                        // 行号
                        var span0Value = spans[0].Trim(new char[] { ' ', '　', '\t' });
                        if (span0Value == "_")
                        {
                            RowIndex = defaultRowNumber;
                        }
                        else
                        {
                            if (int.TryParse(span0Value, out int value))
                            {
                                RowIndex = value;
                            }
                            else { RowIndex = 1; }
                        }

                        // 列号
                        var span1Value = spans[1].Trim(new char[] { ' ', '　', '\t' });
                        if (span1Value == "_")
                        {
                            ColumnIndex = leftCellSpansCount + 1;
                            // 只有内容部件才支持自动计算列宽和列号
                            CountWidthToAutoColumnIndexManager = (WidgetType == ReporterWidgetType.ContentWidget);
                        }
                        else
                        {
                            if (int.TryParse(span1Value, out int value2))
                            {
                                ColumnIndex = value2;
                            }
                            else ColumnIndex = 1;
                            CountWidthToAutoColumnIndexManager = false;
                        }

                        // 行数
                        var span2Value = spans[2].Trim(new char[] { ' ', '　', '\t' });
                        if (span2Value == "_")
                        {
                            RowsCount = -1;  // 表示扩展到所有行
                        }
                        else
                        {
                            if (int.TryParse(span2Value, out int value3))
                            {
                                RowsCount = value3;
                            }
                            else RowsCount = 1;
                        }

                        break;
                    }
                case 4:
                    {
                        // 行号、列号、行数、列数
                        // 行号
                        var span0Value = spans[0].Trim(new char[] { ' ', '　', '\t' });
                        if (span0Value == "_")
                        {
                            RowIndex = defaultRowNumber;
                        }
                        else
                        {
                            if (int.TryParse(span0Value, out int value))
                            {
                                RowIndex = value;
                            }
                            else { RowIndex = 1; }
                        }

                        // 列号
                        var span1Value = spans[1].Trim(new char[] { ' ', '　', '\t' });
                        if (span1Value == "_")
                        {
                            ColumnIndex = leftCellSpansCount + 1;
                            // 只有内容部件才支持自动计算列宽和列号
                            CountWidthToAutoColumnIndexManager = (WidgetType == ReporterWidgetType.ContentWidget);
                        }
                        else
                        {
                            if (int.TryParse(span1Value, out int value2))
                            {
                                ColumnIndex = value2;
                            }
                            else ColumnIndex = 1;
                            CountWidthToAutoColumnIndexManager = false;
                        }

                        // 行数
                        var span2Value = spans[2].Trim(new char[] { ' ', '　', '\t' });
                        if (span2Value == "_")
                        {
                            RowsCount = -1;  // 表示扩展到所有行
                        }
                        else
                        {
                            if (int.TryParse(span2Value, out int value3))
                            {
                                RowsCount = value3;
                            }
                            else RowsCount = 1;
                        }

                        // 列数
                        var span3Value = spans[3].Trim(new char[] { ' ', '　', '\t' });
                        if (span3Value == "_")
                        {
                            ColumnsCount = -1;  // 表示扩展到所有列

                            // 要小心，这种自动扩展到尾部的列，不能加列号
                            CountWidthToAutoColumnIndexManager = false;
                        }
                        else
                        {
                            if (int.TryParse(span3Value, out int value4))
                            {
                                ColumnsCount = value4;
                            }
                            else ColumnsCount = 1;
                        }
                        break;
                    }
            }

            return;
        }

        protected void RefreshBarLocation()
        {
            if (string.IsNullOrWhiteSpace(Text))
            {
                RowIndex = 1;
                ColumnIndex = 1;
                RowsCount = 1;
                ColumnsCount = 1;
                return;
            }

            var match = RegLocation.Match(Text);
            if (match.Success == false)
            {
                RowIndex = 1;
                ColumnIndex = 1;
                RowsCount = 1;
                ColumnsCount = 1;
                return;
            }

            this.Text = this.Text.Substring(match.Length).Trim();

            var locationTxt = match.Value.Trim(new char[] { ',', '，', ' ', '　', '\t', '(', '（', ')', '）' });
            locationTxt = Regex.Replace(locationTxt, @"[_\-—]{1,}", "_");
            var spans = locationTxt.Split(new char[] { ',', '，', }, StringSplitOptions.None);

            switch (spans.Length)
            {
                case 1:
                    {
                        // 只有位置号
                        var span0Value = spans[0].Trim(new char[] { ' ', '　', '\t' });
                        if (int.TryParse(span0Value, out int value))
                        {
                            LocateAreaIndex = value;
                        }
                        else { LocateAreaIndex = 1; }
                        break;
                    }
                case 2:
                    {
                        // 位置号、占据区域数
                        // 位置号
                        var span0Value = spans[0].Trim(new char[] { ' ', '　', '\t' });

                        if (int.TryParse(span0Value, out int value))
                        {
                            LocateAreaIndex = value;
                        }
                        else { LocateAreaIndex = 1; }

                        // 占边栏几个区域：实际布局时（在MiniReporterEdit.cs中）只要大于 1，均视为占满整个边栏，其它数字均视为只占1个边栏子区域。
                        var span1Value = spans[1].Trim(new char[] { ' ', '　', '\t' });
                        if (string.IsNullOrWhiteSpace(span1Value))
                        {
                            LocateAreasCount = 1;
                        }
                        else
                        {
                            if (int.TryParse(span1Value, out int value2))  // 注意：这里只应使用数字！！
                            {
                                LocateAreasCount = value2;
                            }
                            else
                            {
                                if (span1Value.Trim() == "_")
                                {
                                    LocateAreasCount = 3;
                                }
                                else
                                {
                                    LocateAreasCount = 1;
                                }
                            }
                        }
                        break;
                    }
            }
        }

        /// <summary>
        /// 此方法用于在添加边框内容部件时自动按位置设置对齐方式。
        /// 只有内容部件才应调用此方法，其它线、框部件无意义，即使调用也不产生任何作用。
        /// </summary>
        public void SetAligmentByArea()
        {
            if (this is ReporterContentWidget == false) return;
            switch (this.LocateAreaIndex)
            {
                case 1: this.Alignment = TextAlignment.Left; break;
                case 2: this.Alignment = TextAlignment.Center; break;
                case 3: this.Alignment = TextAlignment.Right; break;
                case 4: this.Alignment = TextAlignment.Left; break;
                case 5: this.Alignment = TextAlignment.Center; break;
                case 6: this.Alignment = TextAlignment.Right; break;
                case 7: this.VerticalAlignment = System.Windows.VerticalAlignment.Top; break;
                case 8: this.VerticalAlignment = System.Windows.VerticalAlignment.Center; break;
                case 9: this.VerticalAlignment = System.Windows.VerticalAlignment.Bottom; break;
                case 10: this.VerticalAlignment = System.Windows.VerticalAlignment.Top; break;
                case 11: this.VerticalAlignment = System.Windows.VerticalAlignment.Center; break;
                case 12: this.VerticalAlignment = System.Windows.VerticalAlignment.Bottom; break;
            }
        }

        /// <summary>
        /// 整个页面被分出13个可用区域，索引如下：
        /// 0 版芯（除四边多外的区域）——按网格坐标布局；
        /// 1-3，页眉（上边栏）从左向右均分为三个区域；
        /// 4-6，页脚（下边栏）从左向右均分为三个区域；
        /// 7-9，左边栏，从上向下均分为三个区域；
        /// 10-12，右边栏，从上向下均分为三个区域。
        /// </summary>
        public int LocateAreaIndex { get; set; } = 0;

        /// <summary>
        /// 为简化功能实现，任意一个部件，只要此值大于 1，就占满所在边栏全部三个子区域。
        /// </summary>
        public int LocateAreasCount { get; set; } = 1;
        public WidgetDisplayMode? BarDisplay { get; internal set; } = null;

        /// <summary>
        /// 仅外框部件使用的装饰器。没有对应的“默认外框装饰器”——因为使用场景极少。
        /// </summary>
        public bool Adorner { get; set; } = false;
    }

    public class ReporterContentWidget : ReporterWidget
    {
        public ReporterContentWidget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            this.WidgetType = ReporterWidgetType.ContentWidget;
        }

        public ReporterContentWidget(string text) : base(text)
        {
            this.WidgetType = ReporterWidgetType.ContentWidget;
        }
    }

    public class ReporterLineWidget : ReporterWidget
    {
        public ReporterLineWidget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            this.WidgetType = ReporterWidgetType.LineWidget;
        }

        public ReporterLineWidget(string text) : base(text)
        {
            this.WidgetType = ReporterWidgetType.LineWidget;
        }
    }

    /// <summary>
    /// 文本部件，用于呈现文本。
    /// </summary>
    public class ReporterTextWdiget : ReporterContentWidget
    {
        public ReporterTextWdiget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            widgetTypeName = "ReporterTextWdiget";
        }

        public ReporterTextWdiget(string text) : base(text)
        {
            widgetTypeName = "ReporterTextWdiget";
        }
    }

    public class ReporterTextFieldWdiget : ReporterContentWidget, IFieldWidget
    {
        public ReporterTextFieldWdiget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            widgetTypeName = "ReporterTextFieldWdiget";
        }

        public ReporterTextFieldWdiget(string text) : base(text)
        {
            widgetTypeName = "ReporterTextFieldWdiget";
        }

        public string FieldName { get { return this.Text; } set { this.Text = value; } }
    }

    public class ReporterCharsWidget : ReporterContentWidget
    {
        public ReporterCharsWidget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        { }

        public ReporterCharsWidget(string text) : base(text)
        { }

        private static Regex fillCharRegex;
        private static Regex FillCharRegex { get { return fillCharRegex; } }

        static ReporterCharsWidget()
        {
            fillCharRegex = new Regex(@"[\[【].*[\]】]");
        }

        public string Chars { get; set; } = "";

        public string FillChars { get; set; } = "";

        public string NumberText { get; set; } = "";

        /// <summary>
        /// 指示此部件是否被视为考试证号填涂位置。此时应写成：
        ///     ；新字符行：（1，5）[^]0123456789
        /// 也就是说，当填充字符被设置为 ^ 时，无论后面选项字符是数字还是字母，均视为考试证号。
        /// 这样既可以支持全数字考试证号，也可以支持带字母的考试证号。
        /// </summary>
        public bool IsIdNumberWidget { get; set; } = false;

        protected void LoadChars(string text)
        {
            if (string.IsNullOrEmpty(text))
            {
                Chars = "";
                FillChars = "";
                IsIdNumberWidget = false;
            }
            else
            {
                var matchFillChar = FillCharRegex.Match(text);
                if (matchFillChar.Success)
                {
                    Chars = text.Substring(matchFillChar.Index + matchFillChar.Length);
                    FillChars = matchFillChar.Value.Trim(new char[] { '[', ']', '【', '】' });
                    IsIdNumberWidget = FillChars == "^";

                    if (IsIdNumberWidget == false && FillChars != null && (FillChars.Contains("/") || FillChars.Contains("\\")))
                    {
                        // 说明写成了类似下面这样
                        //     ；新字符行：（1，2）【12/ac】abcd
                        // 这样的写法，/ 前的是题号，/ 后面的是参考答案
                        var spans = FillChars.Split(new char[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries);
                        if (spans.Length == 1)
                        {
                            this.FillChars = spans[0]; // 去除斜杠字符
                        }
                        else if (spans.Length >= 2)  // 只取前两个
                        {
                            this.NumberText = spans[0];
                            this.FillChars = spans[1];
                        }
                    }
                }
                else
                {
                    Chars = text;
                    FillChars = "";
                    NumberText = "";
                    IsIdNumberWidget = false;
                }
            }
        }
    }

    public class ReporterCharsRowWdiget : ReporterCharsWidget
    {
        public ReporterCharsRowWdiget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            widgetTypeName = "ReporterCharsRowWdiget";

            LoadChars(this.Text);

            // 列数自动计算、行数固定为1
            if (string.IsNullOrEmpty(NumberText))
            {
                this.ColumnsCount = this.Chars.Length;  // 不要留空白格，不好，就这样
            }
            else
            {
                this.ColumnsCount = this.Chars.Length + 1;  // 加题号
            }
            this.RowsCount = 1;
        }

        public ReporterCharsRowWdiget(string text) : base(text)
        {
            widgetTypeName = "ReporterCharsRowWdiget";

            LoadChars(this.Text);

            // 列数自动计算、行数固定为1
            if (string.IsNullOrEmpty(NumberText))
            {
                this.ColumnsCount = this.Chars.Length;  // 不要留空白格，不好，就这样
            }
            else
            {
                this.ColumnsCount = this.Chars.Length + 1;  // 加题号
            }
            this.RowsCount = 1;
        }

    }

    public class ReporterCharsColumnWdiget : ReporterCharsWidget
    {
        public ReporterCharsColumnWdiget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            widgetTypeName = "ReporterCharsColumnWdiget";

            LoadChars(text);

            // 行数自动计算、列数固定为1
            this.RowsCount = this.Chars.Length;  // 不要留空白格，不好，就这样
            this.ColumnsCount = 1;
        }

        public ReporterCharsColumnWdiget(string text) : base(text)
        {
            widgetTypeName = "ReporterCharsColumnWdiget";

            LoadChars(text);

            // 行数自动计算、列数固定为1
            this.RowsCount = this.Chars.Length;  // 不要留空白格，不好，就这样
            this.ColumnsCount = 1;
        }
    }

    public class ReporterHLineWidget : ReporterLineWidget
    {
        public ReporterHLineWidget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            widgetTypeName = "ReporterHLineWidget";
        }

        public ReporterHLineWidget(string text) : base(text)
        {
            widgetTypeName = "ReporterHLineWidget";
        }
    }

    public class ReporterVLineWidget : ReporterLineWidget
    {
        public ReporterVLineWidget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            widgetTypeName = "ReporterVLineWidget";
        }

        public ReporterVLineWidget(string text) : base(text)
        {
            widgetTypeName = "ReporterVLineWidget";
        }
    }

    /// 此部件只用于绘制外框（或网格），比单个绘制线条方便得多，又可解决辅助线不能指定绘制区域和行数、列数的问题。
    /// 一个网格部件由以下部分组成：
    /// 1. 一个外框；
    /// 2. 若干竖线（按 BaseColumnsCount，每指定数量的坐标列绘制一条右竖线）；
    /// 3. 若干横线（按 BaseRowsCount，每指定数量的坐标行绘制一条底横线）。
    public class ReporterBoxWidget : ReporterLineWidget
    {
        public ReporterBoxWidget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            widgetTypeName = "ReporterBoxWidget";

            //Text （3，1，_，_）{ 3，2}
            string tail;
            var matchLocation = RegLocation.Match(text);
            if (matchLocation.Success)
            {
                tail = text.Substring(matchLocation.Length);
            }
            else
            {
                tail = text;
            }

            tail = tail.Trim();
            if (tail.StartsWith("_") || tail.StartsWith("-") || tail.StartsWith("—"))
            {
                this.BackgroundLayer = true;
                tail = tail.Trim(new char[] { '_', '-', '—' });
            }
            else this.BackgroundLayer = false;

            tail = tail.Trim(new char[] { ' ', '　', '\t', '{', '}', '｛', '｝' });

            var spans = tail.Split(new char[] { ',', '，' });

            if (spans == null)
            {
                BaseRowsCount = 0;
                BaseColumnsCount = 0;
            }
            else
            {
                if (spans.Length <= 0)
                {
                    BaseRowsCount = 0;
                    BaseColumnsCount = 0;
                }
                else if (spans.Length == 1)
                {
                    // 只指定列数
                    if (int.TryParse(spans[0].Trim(), out int value))
                    {
                        BaseColumnsCount = value;
                    }
                    else BaseColumnsCount = 0;
                }
                else if (spans.Length >= 2)
                {
                    if (int.TryParse(spans[0].Trim(), out int value1))
                    {
                        BaseRowsCount = value1;
                    }
                    else BaseRowsCount = 0;

                    if (int.TryParse(spans[1].Trim(), out int value2))
                    {
                        BaseColumnsCount = value2;
                    }
                    else BaseColumnsCount = 0;
                }
            }
        }

        public ReporterBoxWidget(string text) : base(text)
        {
            widgetTypeName = "ReporterBoxWidget";

            // 在四边栏中不支持网格线效果，所以这里无须继续处理
        }

        /// <summary>
        /// 在底层时，只绘制网格线，不绘制外框；
        /// 在上层时，只绘制外框，不绘制网格线。
        /// </summary>
        public bool BackgroundLayer { get; set; } = false;

        /// <summary>
        /// 绘制内部网格线时的基准行倍数。这个数字决定跨几列绘制一条横线。
        /// 此值为 0 时，不绘制横线。
        /// </summary>
        public int BaseRowsCount { get; set; } = 0;

        /// <summary>
        /// 绘制内部网格线时的基准列倍数。这个数字决定跨几列绘制一条竖线。
        /// 此值为 0 时，不绘制竖线。
        /// </summary>
        public int BaseColumnsCount { get; set; } = 0;
    }

    public enum SlashLineDirection
    {
        /// <summary>
        /// 正斜线。
        /// </summary>
        TopRightToBottomLeft,

        /// <summary>
        /// 反斜线。
        /// </summary>
        LeftTopToRightBottom,
    }

    public class ReporterSlashLineWidget : ReporterLineWidget
    {
        public ReporterSlashLineWidget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            widgetTypeName = "ReporterSlashLineWidget";

            if (string.IsNullOrWhiteSpace(text))
            {
                Direction = SlashLineDirection.TopRightToBottomLeft;
            }
            else
            {
                var match = RegLocation.Match(text);
                if (match.Success)
                {
                    var tail = text.Substring(match.Index + match.Length).Trim();

                    if (string.IsNullOrWhiteSpace(tail) || "正斜线|/|正斜|正".Contains(tail))
                    {
                        Direction = SlashLineDirection.TopRightToBottomLeft;
                    }
                    else
                    {
                        Direction = SlashLineDirection.LeftTopToRightBottom;
                    }
                }
            }
        }

        public ReporterSlashLineWidget(string text) : base(text)
        {

            widgetTypeName = "ReporterSlashLineWidget";

            if (string.IsNullOrWhiteSpace(text))
            {
                Direction = SlashLineDirection.TopRightToBottomLeft;
            }
            else
            {
                var match = RegLocation.Match(text);
                if (match.Success)
                {
                    var tail = text.Substring(match.Index + match.Length).Trim();

                    if (string.IsNullOrWhiteSpace(tail) || "正斜线|/|正斜|正".Contains(tail))
                    {
                        Direction = SlashLineDirection.TopRightToBottomLeft;
                    }
                    else
                    {
                        Direction = SlashLineDirection.LeftTopToRightBottom;
                    }
                }
            }
        }

        public SlashLineDirection Direction { get; }
    }

    /// <summary>
    /// 图像部件，用于呈现图像。
    /// </summary>
    public class ReporterImageWidget : ReporterContentWidget
    {
        public ReporterImageWidget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            widgetTypeName = "ReporterImageWidget";
        }

        public ReporterImageWidget(string text) : base(text)
        {
            widgetTypeName = "ReporterImageWidget";
        }

        public string ImageFileFullPath { get { return this.Text; } }
    }

    /// <summary>
    /// 图像字段部件，用于呈现图像。
    /// </summary>
    public class ReporterImageFieldWidget : ReporterContentWidget, IFieldWidget
    {
        public ReporterImageFieldWidget(string text, int defaultRowNumber, int leftCellSpansCount) : base(text, defaultRowNumber, leftCellSpansCount)
        {
            widgetTypeName = "ReporterImageFieldWidget";
        }

        public ReporterImageFieldWidget(string text) : base(text)
        {
            widgetTypeName = "ReporterImageFieldWidget";
        }

        public string ImageFileFullPath { get { return this.Text; } }

        public string FieldName
        {
            get
            {
                var text = this.Text.Trim();
                if (string.IsNullOrWhiteSpace(text)) return "";

                var match = RegLocation.Match(text);
                if (match.Success)
                {
                    return text.Substring(match.Index + match.Length).Trim();
                }
                else return text.Trim();
            }
        }
    }
    /// <summary>
    /// 二维码部件，可自动生成二维码图片。
    /// </summary>
    public class ReporterQrCoderWidget : ReporterContentWidget
    {
        public ReporterQrCoderWidget(string text, int defaultRowNumbert, int leftCellSpansCount) : base(text, defaultRowNumbert, leftCellSpansCount)
        {
            widgetTypeName = "ReporterQrCoderWidget";
        }

        public ReporterQrCoderWidget(string text) : base(text)
        {
            widgetTypeName = "ReporterQrCoderWidget";
        }

        public string QrCoderText { get { return string.IsNullOrWhiteSpace(this.Text) ? Globals.AppName : this.Text; } }

    }

    /// <summary>
    /// 二维码部件，可自动生成二维码图片。
    /// </summary>
    public class ReporterQrCoderFieldWidget : ReporterContentWidget, IFieldWidget
    {
        public ReporterQrCoderFieldWidget(string text, int defaultRowNumbert, int leftCellSpansCount) : base(text, defaultRowNumbert, leftCellSpansCount)
        {
            widgetTypeName = "ReporterQrCoderFieldWidget";
        }
        public ReporterQrCoderFieldWidget(string text) : base(text)
        {
            widgetTypeName = "ReporterQrCoderFieldWidget";
        }

        public string QrCoderText { get { return string.IsNullOrWhiteSpace(this.Text) ? Globals.AppName : this.Text; } }

        public string FieldName
        {
            get
            {
                var text = this.Text.Trim();
                if (string.IsNullOrWhiteSpace(text)) return "";

                var match = RegLocation.Match(text);
                if (match.Success)
                {
                    return text.Substring(match.Index + match.Length).Trim();
                }
                else return text.Trim();
            }
        }
    }

    public class ReportScriptCompileExpection : Exception
    {
        public ReportScriptCompileExpection(string msg) : base(msg)
        {

        }

        public ReportScriptCompileExpection(string msg, int lineNumber) : base(msg)
        {
            this.LineNumber = lineNumber;
        }

        public int LineNumber { get; set; }
    }

    public interface IFieldWidget
    {
        string FieldName { get; }
    }
}
